← Back toIntersectionObserver with React

Lazy load a video

Written byPhuoc Nguyen
Created
28 Jan, 2024
Lazy loading is an awesome technique that delays the loading of non-essential resources, such as images and videos, until they're actually needed. This can make a huge difference in how quickly a website loads, especially for pages with a lot of media content.
In one of our previous posts, we showed you how to lazy load images using the `IntersectionObserver` API. In this post, we'll take it a step further and show you how to use the same technique to lazy load videos too.

Using IntersectionObserver to detect when a video is visible

The `IntersectionObserver` API is a powerful tool that lets you know when an element enters or leaves the viewport. This is particularly useful for lazy loading because we only want to load a video when the user can actually see it.
Here's the code snippet that shows how we can do it:
jsx
const videoRef = React.useRef<HTMLVideoElement>(null);

React.useEffect(() => {
const video = videoRef.current;
if (!video) {
return;
}

const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
video.src = video.dataset.src;
observer.unobserve(video);
}
});
}, {
threshold: 0,
});

observer.observe(video);

return () => {
observer.unobserve(video);
};
}, []);

return (
<video
ref={videoRef}
data-src="/path/to/video.mp4"
controls
/>
);
In this example, we create a reference called `videoRef` and attach it to the `<video>` element. Then, we use a `useEffect` hook to create a new instance of `IntersectionObserver` that will watch the video element.
When the video becomes visible (i.e., it intersects with the viewport), the observer callback is triggered. Inside the callback, we set the `src` attribute of the video to the value of the `data-src` attribute, which contains the actual video URL.
To prevent the video from being loaded again if it leaves and re-enters the viewport, we unobserve the video element.
Check out the demo below to see it in action!
Video credit: City traffic by @xat-ch

Displaying a loading indicator

It's always a good idea to show a loading indicator while the video is loading. This lets the user know that something is happening. You can easily achieve this by conditionally rendering a loading spinner based on the video's loading state.
tsx
const [isLoading, setIsLoading] = React.useState(true);

const handleLoadedData = () => {
setIsLoading(false);
};

return (
<div className="container">
{isLoading && <div className="loading">Loading...</div>}
<video
ref={videoRef}
data-src="/path/to/video.mp4"
onLoadedData={handleLoadedData}
controls
/>
</div>
);
To improve the user experience, we can add a `isLoading` state variable that starts out as `true`. We also attach an `onLoadedData` event handler to the video that sets `isLoading` to `false` once the video metadata has loaded.
To visually indicate to the user that the video is loading, we conditionally render a loading indicator element in the JSX if `isLoading` is `true`. This loading indicator can be any kind of spinner or placeholder you want.
Check out the demo below. Scroll down to the bottom to see the loading indicator appear before the video is completely loaded.

Conclusion

One way to improve your website's performance is by using `IntersectionObserver` to lazy load videos. This means that the videos won't load until the user can see them, which reduces page load time and saves bandwidth.
Don't forget to add a loading indicator when you implement lazy loading. This will let users know that content is coming and improve their experience on your website.

Questions? 🙋

Do you have any questions about front-end development? If so, feel free to create a new issue on GitHub using the button below. I'm happy to help with any topic you'd like to learn more about, even beyond what's covered in this post.
While I have a long list of upcoming topics, I'm always eager to prioritize your questions and ideas for future content. Let's learn and grow together! Sharing knowledge is the best way to elevate ourselves 🥷.
Ask me questions

Recent posts ⚡

Newsletter 🔔

If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.
Phước Nguyễn