Video is the heaviest type of media used on websites. You're talking almost 4 megabytes of video on mobile devices for a median page with video. That weight has a huge impact on performance, the data cost for a user, the hosting cost for a website owner, and energy usage. How can we reduce the size of video content served upfront?
A big part of the problem is that often one big video file is being served to everyone. Ideally we want to serve identical video content, just a larger or smaller video depending on the device's viewport width and resolution. How do we do this?
Can we use the scrset
and sizes
attributes for video?
No!
You might be familiar with using the srcset
and sizes
attributes used for images to provide responsive image sets. The <video>
element does not permit usage of the srcset
attribute on accompanying <source>
elements.
There is a proposal to add support for the srcset
and sizes
attributes for video files to the HTML standard.
What do we do instead?
How can we reduce the size of video content served?
You have 2 main options.
The responsive HTML approach
You can use the media
attribute on the <source>
element to provide a media query. You can conditionally serve a video file depending on the browser's width, resolution, or orientation. Something like this:
<video>
<source src="/video/small.mp4" media="(max-width: 599px)">
<source src="/video/large.mp4">
</video>
In this example, if the browser viewport is less than 600 pixels wide the browser will use the small.mp4
video file, otherwise it will use the large.mp4
video file.
The peculiar thing about this feature is that it was deleted from the HTML standard in 2014. This was partly based on claims that other methods were superior. That led to Chrome and Firefox pulling the stable code out of their codebases to comply with the changed standard, however Safari left it be. It took a request from Scott Jehl in 2021 to get the functionality restored.
The media
attribute is supported in all browsers again as far as I can tell. The web.dev blog has a somewhat vague note on responsive video in their "What's new in the web" article - it's not clear if they are referring to the media
attribute or the srcset
attribute.
I recommend reading How to Use Responsive HTML Video article for more details.
Use a streaming protocol
Another option to reduce the weight of video content is use a streaming protocol such as the HTTP Live Streaming (HLS) standard. The most important feature of HLS is its ability to adapt the bitrate of the video to the actual speed of the connection. HLS videos are encoded in different resolutions and bitrates.
Streaming protocols are more complicated to implement than the responsive HTML approach. HLS is supported by Safari, but requires some JavaScript for the other browsers. This is a bummer.
The HTML side of the equation is simple. You use a <video>
element with a source stream.
<!-- streaming video -->
<video src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"></video>
You can read more about HLS in this article.
I discussed how to optimise YouTube embeds in a previous post if you are going down that route with video. Do not use the default embed code snippet!!
Written by Rob O'Leary
Subscribe to web feed for the latest articles.
© Rob OLeary 2024
Top comments (6)
Love the information. Does hosting with something like Vimeo embeds reduce some of the optimization needed? I assume that's some of the strength of using them, they figure out how to adjust to the user's connection speeds, etc.
There are pros and cons of the approaches. If the embed uses streaming, then it can serve video according to the bitrate available when the video is played. Since an embed is an
iframe
plus JavaScript, it is more heavyweight than avideo
. The initial download can be higher unless you defer loading or can use lazy loading. I spoke of this scenario in another post on YouTube embeds.Thanks @robole - great write up on the YT embeds, that lite package looks incredible. We were displaying a Vimeo-hosted auto-looping video on our home page, and I'm struggling to get my head around if its harming our page performance. As its the home page, most of our converting traffic never sees it, so its basically a fluff piece for our execs to get warm and fuzzy about. Lightening the load times would make me much happier about its existence.
Another option if its not a long video, is converting it to an animated image format such as webp. You could add
loading="lazy"
to the<img>
tag to lazy load it.