Search

YouTube Embeds are Bananas Heavy and it’s Fixable

TL;DR: YouTube Embeds are like 1.3MB in size with no shared resources between multiple embeds. Using a <lite-youtube> Web Component is more like 100k, does share resources, and sacrifices no functionality.

You can put a YouTube video on any website. They help you do it. Under the Share menu right on youtube.com there is an option to <> Embed and you’ll see bit of HTML with an <iframe> in it.

<iframe>s are never wonderful for performance, but they make sense for protected third-party content.

This is what I’m getting as I write:

<iframe 
  width="560" 
  height="315" 
  src="https://www.youtube.com/embed/LN1TQm942_U?si=EfW_M4bEHEO-idL3"
  title="YouTube video player"
  frameborder="0"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
  referrerpolicy="strict-origin-when-cross-origin"
  allowfullscreen>
</iframe>Code language: HTML, XML (xml)

If I were Team YouTube, I’d get loading="lazy" on there to help with performance right away. No need for videos that aren’t even visible on the page to load right away.

<iframe 
  ...
  loading="lazy"
  >
</iframe>
Code language: HTML, XML (xml)

Plus I’d put some inline styles on there to keep the video fluid and maintain the original aspect ratio. Or you could target these and do that yourself in CSS. Here’s assuming the videos are the standard 16 / 9 aspect ratio:

iframe[src^="https://www.youtube.com/embed/"] {
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
}Code language: CSS (css)

But… let’s not keep this HTML at all. I’m sure you read this blog post title, but let’s put a point on it:

On a page with literally nothing at all on it other than a YouTube Embed, we’re looking at:

  • 32 requests
  • 1.3 MB of data transfer
  • 2.76s to load the page on my current WiFi connection

Zach Leatherman, equally exasperated by this, noted:

The weight also grows linearly with every embed—resources are not shared: two embeds weigh 2.4 MB; three embeds weigh 3.6 MB (you get the idea).

Wow.

Looks like sizes are up a bit since Zach last looked as well.

The Appearance & Functionality

This is what you get from a YouTube Embed:

  • You see a “poster” image of the video
  • You see the title of the video
  • You see a big play button — click it to play the video

This is very little UI and functionality, which is fine! We can absolutely do all this without this many resources.

Why is it this way? 🤷‍♀️

I don’t think we have any good answers here. In fact, I heard from a little birdie who ran it up the pole that they have tested lighter embeds and found them to reduce engagement. 😭

I’m just gonna straight up say I don’t believe it. It’s like when Google told us that taking up half the screen with AI generated answers led to people clicking on third-party results more, but then refused to show data or allow us to track those clicks ourselves.

And hey — sometimes there are unexpected results in testing. That’s why we test instead of guess. But because this is so counterintuitive and offtrack for so many other similar performance testing situations, this bears deeper scrutiny. It would benefit from an opening of the methodology and data.

Like if you tell me that if you hit people with a stick and they smile more, I’m gonna want you to stop until we can look at what’s going on there.

I really wish I could find a good link for this, but there is a famous story from YouTube engineers way-back-when who made a much lighter video page and put it into testing. They found, quite counterintuitively, that average page load times went up. But with a deeper look, they found that the lighter page was able to reach more people, including people on low-power low-internet-speed devices who were able to actually use YouTube for the first time, and them using it much more slowed those averages. That’s awesome! The speed of using the site was up relatively for everyone. The metric of the average page load speed was a red herring and ultimately not meaningful.

How do we know that’s not the same kind of thing happening here?

Remember the implications of all these resources isn’t just a little inconvenience. YouTube is so enormous we’re talking incredible amounts of wasted electricity and thus carbon output. Pulling a megabyte of data off every single YouTube Embed would be an incredible win all around. I might even say not improving this is environmentally negligent.

The Solution is to Replicate the Embed Experience Another Way. There are Open Source Web Components That Do It Well.

With a little dab of irony, Google’s own performance champion Paul Irish has had a web component doing just this for years and years and years:

lite-youtube-embed

The pitch is solid:

Provide videos with a supercharged focus on visual performance. This custom element renders just like the real thing but approximately 224× faster.

Two hundred and twenty four times faster. Which of course involves much less data transfer.

And I’d like to be very clear, also does the exact same thing as the default embed:

  • You see a “poster” image of the video
  • You see the title of the video
  • You see a big play button — click it to play the video

You lose nothing and gain tons of speed, efficiency, and default privacy.

Using Lite YouTube Embed

  1. Link up the JavaScript to instantiate the Web Component
  2. Use it

You could install it from npm or copy and paste a copy into your own project or whatever. Or link it from a CDN:

import "https://esm.sh/lite-youtube-embed";Code language: JavaScript (javascript)

That’s like this:

But the best way to use it is right in the README:

Use this as your HTML, load the script asynchronously, and let the JS progressively enhance it.

<script defer src="https://cdnjs.cloudflare.com/ajax/libs/lite-youtube-embed/0.3.2/lite-yt-embed.js"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lite-youtube-embed/0.3.2/lite-yt-embed.css" integrity="sha512-utq8YFW0J2abvPCECXM0zfICnIVpbEpW4lI5gl01cdJu+Ct3W6GQMszVITXMtBLJunnaTp6bbzk5pheKX2XuXQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<lite-youtube videoid="ogfYd705cRs" style="background-image: url('https://i.ytimg.com/vi/ogfYd705cRs/hqdefault.jpg');">
  <a href="https://youtube.com/watch?v=ogfYd705cRs" class="lty-playbtn" title="Play Video">
    <span class="lyt-visually-hidden">Play Video: Keynote (Google I/O '18)</span>
  </a>
</lite-youtube>Code language: HTML, XML (xml)

With async loaded JavaScript, note the background-image is put into the HTML so it can all look right before the JavaScript loads.

Alternatives

Learn to Work with Web Components

Frontend Masters logo

Dave Rupert's course on Web Components will get you entirely up to speed on this powerful native web platform technology. As Dave says, it's HTML with Superpowers.

10 responses to “YouTube Embeds are Bananas Heavy and it’s Fixable”

  1. Avatar Nigel says:

    I totatally agree then video embeds are way too big and would like to suggest my own alternative Responsive Video Poster https://nigelotoole.github.io/responsive-video-poster/ This lazy loads embeds on user interaction and gives full styling control of video placeholders. It also works with any video site embeds and native videos.

  2. Avatar Farai says:

    I should work on getting this implemented in Hugo.

    As for the link on how YouTube’s attempts to reduce performance increased average load times, That’s this post Page Weight Matters by Chris Zacharias (https://blog.chriszacharias.com/page-weight-matters).

  3. Avatar Jan says:

    Another idea, show the poster image with a play icon on top with a standard HTML link so it opens the video on YouTube. Even lighter, no JavaScript and… no Google tracking as long as you don’t click the link!

    • Avatar Ed Sawicki says:

      This is what I do. Plus, I can choose the image used for the poster image and I use Imagemagick to superimpose the play icon.

  4. Avatar Evan says:

    The only issue I’ve run into with these kind of poster stand-ins, is that you have to click the play button twice on mobile (Safari, iOS). Once to load the YouTube player, and then again on the player itself. It’s not the end of the world, I just wish there was a completely perfect solution.

    • Avatar Chris Coyier says:

      Ah you’re right! I hadn’t realized that. That is indeed a deviation in behavior for the worse. Arm chair commentary, I’d say it’s still worth it, but that actual decision would have to be weighed in context of a real site.

    • Avatar Taj says:

      Maybe I’m missing something but can’t this be fixed by adding &autoplay=1 to the URL so that it plays when it loads?

  5. I made some effort for Django to do the some thing, getting the video image and insert the embed on click (https://pypi.org/project/djangocms-youtube-lazyload/), but this is even more brilliant as it doesn’t require getting the YouTube api key, which is a tedious task to say the least

Leave a Reply