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!!