Lazy-Loading Video Without Surprises
Video can be one of the heaviest things on a page. If it sits well below the fold, downloading it immediately wastes bandwidth and competes with resources the visitor can actually see.
There is no loading="lazy" attribute for <video> like there is for images. The right approach depends on whether playback waits for the user or starts automatically.
A video the user chooses to play
For a normal video with controls, tell the browser not to preload the media:
<video controls preload="none" poster="video.jpg">
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
</video>
preload="none" is a hint that no video data should be downloaded before playback. Browsers can make their own decisions, so test the result rather than treating it as an absolute command.
The poster gives the visitor something useful to see before the video loads. Optimize that image too; replacing a deferred video with an enormous poster would be a rather literal sideways move.
A video used instead of an animated GIF
Muted looping video can be much smaller than an animated GIF:
<video autoplay muted loop playsinline>
<source src="video.webm" type="video/webm">
<source src="video.mp4" type="video/mp4">
</video>
To defer it, keep the real URLs in data attributes and move them into src when an Intersection Observer sees the video approaching the viewport. Call video.load() after updating the sources.
This requires JavaScript, and the non-JavaScript fallback should be deliberate. Also respect reduced-motion preferences. An endlessly moving decoration may be cheap in bytes and still expensive in attention.
I would use preload="none" for user-initiated playback and reach for Intersection Observer only when an autoplaying video genuinely needs to start near the viewport. The easiest video to optimize is still the one the page did not need.