Lazy load embedded YouTube videos
Tags: html, youtube, performance
Published: 2019-08-07 15:04:06

I was working on this simple static website that should have an YouTube video displayed right on the landing page. So I went my merry way, hopped onto YouTube, snatched the embed code, pasted it into my editor and called it a day.

![YouTube share dialog](https://i.imgur.com/HWKj35i.png)

The thing is the job was specifically to deliver high performance, accessibility and modern practices, so you can imagine my annoyance when I noticed that just for having this `<iframe>` I got this:

![DevTools snapshot showing multiple requests made from YouTube's iframe 🤨️](https://i.imgur.com/IT0tvqp.png)

Plus a few extra requests that my ad blocker handled for me.

That is over 500KB that my users would have to download on top of the website, regardless if they'll watch the video. Do you have any idea [how heavy this might hit your users](https://developers.google.com/web/fundamentals/performance/why-performance-matters/), specially the ones with slow connection or low performing machines? To add insult to injury they'd also be being tracked—Hi Google—for just loading a video they didn't even know was there.

It being a simple static website I wanted to keep my solution to a minimum, so here's what I came up with.

The code for embedding an YouTube video, as of August 2019, goes like this:

```html
<iframe 
  width="560" 
  height="315" 
  src="https://www.youtube.com/embed/Y8Wp3dafaMQ" 
  frameborder="0" 
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen>
</iframe>
```

So I thought what if instead of the actual video I showed just its cover linked to the video? It would still kinda look like an embedded video but it would require only a single image upfront. Thankfully YouTube has an [URL schema for video thumbnails](https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api). 

```html
<a href="https://www.youtube.com/embed/Y8Wp3dafaMQ">
  <img src="https://i3.ytimg.com/vi/Y8Wp3dafaMQ/hqdefault.jpg">
</a>
```

Cool, but I really don't want to have to create a whole new page just for this teeny tiny snippet of code. Well, we're in luck cause `<iframe>` has just the perfect thing for us—the [srcdoc attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-srcdoc). With it you can source the `<iframe>` directly in the hosting page. Just beware that it [won't work on Edge or IE](https://caniuse.com/#search=srcdoc) and that we can't use double quotes.

```html
<iframe 
  ...
  srcdoc="<a href=https://www.youtube.com/embed/Y8Wp3dafaMQ><img src=https://i3.ytimg.com/vi/Y8Wp3dafaMQ/hqdefault.jpg></a>">
</iframe>
```

Finally you'll notice that if we click the image it'll load the video but in a paused state and we would need to click it again to start watching. Fret not, cause the embed video URL supports [player parameters](https://developers.google.com/youtube/player_parameters?playerVersion=HTML5) and among those there's the `autoplay` variable which does exactly what you would expect. Additionally due to browser's default style users on systems with scrollbar—namely not macOS—will see an unnecessary scrollbar, but nothing that a small CSS reset wouldn't fix. 

[Remy Sharp](https://dev.to/remy) pointed out we should keep the `src` as fallback to browsers that don't support `srcdoc`. [Adrian Roselli](https://dev.to/aardrian) suggested a few tweaks to improve accessibility. Also, while applying these suggestions I fixed the image position so it stays centered both horizontally and vertically without resorting to `background-size: cover`. Thank you guys for your feedback! 🤩️

Here's the **final result**:

{% codesandbox qdzu6 %}

The `<iframe>` singled out:

```html
<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/Y8Wp3dafaMQ"
  srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/Y8Wp3dafaMQ?autoplay=1><img src=https://img.youtube.com/vi/Y8Wp3dafaMQ/hqdefault.jpg alt='Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition'><span>▶</span></a>"
  frameborder="0"
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  title="The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"
></iframe>
```

This way all the users will have to download upfront is the cover image, which seems pretty reasonable to me. You can customize it further, e.g. make use of the different thumbnail sizes for different devices, and if you need more control over what the user will load and what features to enable you can always explore the [YouTube Player API](https://developers.google.com/youtube/iframe_api_reference).

If you've got any questions, corrections or suggestions feel free to comment below. Thank you for your time. 😊️