This project is a sample application designed to demonstrate techniques for improving image and video load performance on the web. It showcases various strategies to optimize media content, ensuring faster load times and a better user experience.
To get started with this project, follow these steps:
-
Install Dependencies:
Run the following command to install the necessary dependencies:npm install
-
Start the Development Server:
Use the following command to start the development server:yarn dev
-
Access the Application:
The main application is hosted on the/demoroute. Open your browser and navigate to:http://localhost:3000/demo
- Demonstrates best practices for optimizing image and video loading.
- Provides examples of lazy loading, responsive images, and video streaming.
- Includes a variety of components to showcase different optimization techniques.
Import the ImageKitProvider in layout.jsx
import { ImageKitProvider } from "@imagekit/next";
And then wrap the entire layout in the provider with the urlEndpoint attribute.
<ImageKitProvider urlEndpoint={process.env.NEXT_PUBLIC_IK_URL_ENDPOINT}>
</ImageKitProvider>
Then in Media.jsx component, import the required components, and replace the HTML img and video tags, with the Image and Video components imported
import { Image, Video } from "@imagekit/next";
const Media = ({ src, contentType, poster, ...props }) => {
src = src.replace("https://d1o2glsg6m692z.cloudfront.net/", "");
if (contentType === 'video') {
return <Video src={src} poster={poster} {...props} />;
} else {
return <Image src={src} {...props} />;
}
};
We additionally removed the Cloudfront domain in the existing src as ImageKit will need to use the domain that is associated with ImageKit. After this step, images and videos are automatically compressed, delivered in modern formats like WebP/AVIF/WebM, and use DPR-based responsive image tags.
ImageKit can be used to create video thumbnails as well. You can create the poster URLs for the Video component using the buildSrc utility function in ImageKit SDK. In the Media.jsx component, it will look something like this
if (contentType === 'videoThumbnail') {
let posterURL = buildSrc({
urlEndpoint: process.env.NEXT_PUBLIC_IK_URL_ENDPOINT,
src: `${src}/ik-thumbnail.jpg`,
transformation: [{
width: props.width,
height: props.height,
crop: "at_max"
}]
});
return <Image src={posterURL} {...props} />;
}
In the ProductGallery.jsx component for the thumbnail grid, instead of loading the thumbnail from the URL available from the backend, we can now do it using the ImageKit create thumbnail transformation, as shown below.
contentType={item.type === 'video' ? 'videoThumbnail' : 'image'}
src={item.url}
The same can be replicated for the video that plays in the main selected media box and the ProductGallery component.
The default responsive srcset generated by Next.js, and therefore by the Image component of ImageKit, uses the DPR-based descriptors - 1x and 2x. A better thing to do for images that change with the viewport width is to use width-based descriptors instead. This is done by adding the sizes attribute to the image loading.
For example, for the main selected image in the ProductGallery.jsx component, this is a suitable sizes attribute for the given layout.
sizes="(max-width: 768px) 80vw, (max-width: 1200px) 50vw, 500px"
The main selected image in the Product Gallery needs to be preloaded. This can be done by adding priority="true" to the main image. Other images, by default, are set to load lazily using the browser's native lazy loading functionality. Adding priority="true" to the main image automatically preloads the image in the head section of the page and removes the lazy loading attribute from the image.
GIF images can be optimized significantly by converting them into MP4 or WebM format videos. To do it across the site, you can make a change to the Media component as given below, to load a muted, looping video that mimics a GIF.
if (src.includes('.gif')) {
let gifSrc = `${src}/ik-gif-video.mp4`;
return <Video src={gifSrc} muted loop autoPlay {...props} />;
}
The above changes will address all media-related issues in the Lighthouse report and significantly improve page performance.
ImageKit offers AI transformations for images with the same URL-based transformation API. For example, if you want to change the product image background from a plain grey background to a more natural photographic background, you can add the transformation to the Media where the image loads, as shown below.
transformation={ item.type === 'image' ? [{
"aiChangeBackground" : `prompt-${encodeURIComponent("On a rock with snowy mountains in the background at a distance")}`
}] : undefined }
This project is licensed under the MIT License.