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:
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.
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.
If you want more helpful content like this, feel free to follow me:
Top comments (0)