Lazy-loading is a strategy to identify resources that are not critical for the initial page load, and load them only when needed. It’s a way to reduce page load times. We have the ability to lazy-load images and iframes in browsers via the
<img src="cat.jpg" loading="lazy" alt="felix the cat" >
<iframe src="a4sefRp.html" loading="lazy" title="dancing cat animation"></iframe>
It just made me wonder why the
video element has been overlooked. Is it because most videos live on YouTube now and are embedded on websites via iframes?
When writing an article recently, I had a short screen recording to demo some functionality. I wanted to include it as autoplaying video, similar to where you might use an animated GIF. That’s when I realised there is no native lazy loading for videos.
This nudged me towards converting the video into an animated WebP instead because I can lazy load it. I did not want to go on a tangent to research what people do with videos more at the time, but today I will!
They are 2 distinct use cases for lazy loading videos that are handled differently. Let’s take a look at these to understand the topic better.
This use case is where have controls on the video, and it up the user to play the video.
You can specify the
preload attribute on the
video element to control loading. By providing
preload="none", the browser should be prevented from loading the video data.
<!-- disable preloading -->
<video controls preload="none" width="300" poster="img/cover.jpg">
<source src="files/sample.mp4" type="video/mp4">
On some browsers, the video will be have no background. You can make it look better by using the
poster attribute to provide a preview image.
When the user clicks the play button of the video, then the video will be loaded.
This was my use case. For a README or technical articles, it is common to include a demo of functionality with an autoplaying video.
In this use case,
preload="none" will not work. Typically, when you have the
autoplay attribute to play a video automatically, the browser will load the video! So if you use both together, most browsers will disregard
First let’s prepare the HTML. To not load the videos, we will exclude the
src attribute on the
source elements that point to the video files. Instead we will stash the URL of the videos in the
data-src attribute. And lastly, we will add a “lazy” class to
video to identiy it as a lazy loading participant.
<video class="lazy" autoplay muted loop playsinline width="600" height="300" poster="cover.jpg">
<source data-src="screen-recording.webm" type="video/webm">
<source data-src="screen-recording.mp4" type="video/mp4">
IntersectionObserver API to detect when the
video element with the “lazy” class comes into view, and will add a
src attribute to each
source element and copy the URL from the
Here is the codepen:
You can check in the Network tab in the browser devtools to see it working as you scroll towards the video.
This code does not cover the case where you have the
src attribute in
video by the way! You can adapt it yourself if you want to use it in that way.
For user-initiated playing of videos, the
IntersectionObserver API. It would be nice to have a native version of this. Browser vendors could add a new value for
preload; or could add the same behaviour of the
loading attribute as they have for
Where is the suggestion box? 😄📥