Responsive video - How can we reduce the size of video content served?
Tags: webdev, html, javascript
Published: 2024-07-10 17:21:32

Video is the [heaviest type of media used on websites](https://httparchive.org/reports/page-weight#bytesVideo). 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`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#srcset) and [`sizes`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#sizes) attributes used for images to provide responsive image sets. The [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) element does not permit usage of the `srcset` attribute on accompanying [`<source>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source) elements.

There is a [proposal to add support for the `srcset` and `sizes` attributes for video files](https://github.com/whatwg/html/issues/9446) 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`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source#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:

```html
<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](https://github.com/whatwg/html/commit/c5ec4f6203e199721a879a3267e63520e21a8f8f). 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](https://github.com/whatwg/html/issues/6363) 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](https://web.dev/blog/new-in-the-web-io2024?hl=en#responsive_video) 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](https://scottjehl.com/posts/using-responsive-video/) 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](https://developer.apple.com/streaming/). 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](https://caniuse.com/http-live-streaming), 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.

```html
<!-- streaming video -->
<video src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"></video>
```

You can read more about HLS in [this article](https://www.freecodecamp.org/news/what-is-hls-and-when-to-use-it/).

---

I discussed how to [optimise YouTube embeds in a previous post](https://www.roboleary.net/2024/02/10/youtube-embeds-suck-but.html) if you are going down that route with video. Do *not* use the default embed code snippet!!

---
Written by [Rob O'Leary](https://www.roboleary.net)

[Subscribe to web feed](https://www.roboleary.net/feed.xml) for the latest articles.

<small>© Rob OLeary 2024</small>