Revisiting best practices for the video HTML element

A VHS video cassette is standing up with a measuring tape hanging in front of it.

The video HTML element is slowly falling in line with the img and picture elements. Should we rethink our best practices for video?

Lazy loading

Lazy loading media files is a big performance win. We would like to defer loading media files that are outside of the initial viewport. This behaviour has been normalised for images, but not for videos. I guess a big reason is that most video on web pages are YouTube embeds, which is a bummer for performance.

It has been possible to lazy load a video in HTML through the preload attribute for a long time. However, there are limitations with this method. For example, it always load a video if the autoplay attribute is also present.

HTML
<!-- previous method -->
<video preload="none" poster="img/cover.jpg" controls>
  <source src="screen-recording.webm" type="video/webm">
  <source src="screen-recording.mp4" type="video/mp4">
</video>

Now, you can use the loading attribute on the video HTML element to lazy load a video. Videos lazy loaded in this way will never be loaded until they are visible in the viewport (approxmiately).

HTML
<!-- new  method -->
<video width="600" height="300" loading="lazy" controls>
  <source src="screen-recording.webm" type="video/webm">
  <source src="screen-recording.mp4" type="video/mp4">
</video>

It is best to consider this feature a progressive enhancement for the moment. Browser support for this feature is limited to Chrome currently.

You can upvote this feature on the developer-signals repo to indicate your interest in the feature being available in all browsers. The Interop project uses this an input for choosing which features to pick.

Unloaded videos have a width and height of zero. When it loads, it will cause a cumulative layout shift (CLS). Adding explicit width and height attributes to the video element will prevent this from happening.

Aspect ratio / dimensions

It is recommended to always have explicit width and height attributes on the video element to ensure that a cumulative layout shift is avoided. [1] [2]

Similar to images, it would be beneficial to have your framework/stack add the width and height attributes to every video element on your behalf.

Responsive video

Often one big video file is being served to everyone. Ideally we would like to serve identical video content, just a larger or smaller video depending on the device’s viewport width and resolution. I discussed this responsive video problem in a previous post.

You can use the media attribute on the <source> element to provide a media query to conditionally serve a video file depending on the browser’s width, resolution, or orientation. Something like this:

HTML
<video>
	<source src="/video/small.mp4" media="(max-width: 599px)">
	<source src="/video/large.mp4">
</video>

There is a proposal to add support for the srcset and sizes attributes for video files to the HTML standard. It works the same as for picture. It would be good to see this move forward.

Conclusion

Videos are typically the largest files requested on web pages, yet we give it less thought than images. The video HTML element has most of the capabilities of the img element and picture elements now. We should embrace a similar set of best practices, and push for features such as lazy loading to be adopted by all major browsers. Also, it is worth considering swapping YouTube embeds for video to improve user experience.


  1. Optimize Cumulative Layout Shift (web.dev) - “Always include width and height size attributes on your images and video elements”. ↩︎

  2. HTML video embed element (MDN) - “While explicit width and height attributes are recommended for all videos to avoid layout shift, they are especially important for lazy-loaded ones.”. ↩︎

Tags