YouTube embeds are bloated - do this instead

YouTube embeds are bloated - do this instead

The YouTube iframe embed is bloated. An embed clocks in at over 1MB, and that does not involve loading a single byte of the video. Since an iframe can have a significant say on a page’s loading speed and how quickly it becomes interactive – it is worthwhile to review your usage of YouTube embeds.

The snippet in the embed dialog for youtube does not include loading='lazy'
The HTML snippet for a YouTube embed.

Like I discussed in a previous post on lazy loading, you can lazy load an iframe and it will make a big difference to the perf of a page. The HTML snippet for the YouTube embed does not include lazy loading. In fact, as I will discuss in more detail later, native lazy loading is ignored by YouTube embeds!

Is there any way to cut the weight of the embed to improve the user experience?

What is the weight of a typical YouTube embed?

For example, if I embed the video JavaScript in 100 Seconds by Fireship on a webpage, the following resources are downloaded (compressed weights given):

What’s the alternative to the bloated YouTube embed?

Let’s look at the alternatives to the embed, but exclude searching for alternative services to YouTube.

The alternatives are:

  1. Use a link to the page of the YouTube video!
  2. If you have the access to the video file, you can host the video yourself and use the video element to embed it in a page. You can optimize it by using the preload attribute to lazy load the video. You have a preview placeholder and the video is not loaded!
  3. You can use the lite-youtube-embed JavaScript library to create an optimized YouTube embed. It creates a facade to use Google’s term – a preview placeholder. The video is not loaded.

It is worthwhile to consider these options in the context of your content. I think people embed YouTube videos more often that they need to!

For example, I saw on Deque’s Axe Devtools page that they had a YouTube embed in the hero section. The video is a demostration of the tool and it looks like they produced the video. Is it worth the performance hit to have this video as a YouTube embed? 🤔

axe devtools main page has a YouTube embed in hero section

It may sound silly, but why discount it as an option? It’s a zero kilobyte approach! Do you really need to have the video on your page?

I think using a link to a YouTube video is a good choice when the video is like an aside to what being discussed. Opening a new browser tab is a context switch, so it fits that use case well.

Use the video element

If you produced the video or are allowed to use the video file, then why not embed the video using the video element? No JavaScript is required.

I’m not sure what people’s motivation is for using a YouTube embed for their own video - saving bandwidth on hosting plans, wanting more visibility on YouTube, etc. I generally think that you should skip it if you want to optimize UX.

From a performance point of view, you will be way ahead if you use video like this:

<!-- video is not loaded -->
<video controls preload="none" width="600" poster="img/poster.webp">
<source src="files/demo.mp4" type="video/mp4">
</video>

You will have a preview placeholder for the video and the video is not downloaded.

Use the lite-youtube-embed library

If you want to have a YouTube video embedded in the page but with a lighter approach, you can use lite-youtube-embed. The author claims it is “approximately 224× faster” than the YouTube embed! I suspect the performance improvement is a lot more modest than that! It was created 5 year ago mind you, it is sad in a way that it is still relevent.

The library provides a web component that can be used as a progressive enhancable custom element. If the JavaScript has not loaded, you see a link instead.

<lite-youtube videoid="DHjqpvDnNGE">
<a href="https://www.youtube.com/watch?v=DHjqpvDnNGE"
title="Play Video">
Play JavaScript in 100 Seconds</a>
</lite-youtube>

In essence, the “lite embed” looks like exactly like the YouTube embed, it creates the same placeholder but without the iframe. It has a pseudo-element with a background image for the poster and a stylized play button. When you click the button, it loads the iframe and kicks off playing the video.

This is what the HTML looks like once the script has run (pseudo-elements are omitted):

<lite-youtube videoid="DHjqpvDnNGE" style="background-image: url('https://i.ytimg.com/vi/DHjqpvDnNGE/hqdefault.jpg');">
<a href="https://www.youtube.com/watch?v=DHjqpvDnNGE" title="Play Video">Play JavaScript in 100 Seconds</a>
<button type="button" class="lty-playbtn"><span class="lyt-visually-hidden">Play</span></button>
</lite-youtube>

It does other performance tweaks such as preconnecting to servers too.

Many people use a wrapper for lite-youtube-embed to suit their stack. The repo has listed some for React and Vue.

What is the difference in performance between a YouTube embed, the video element, and the lite youtube embed?

Using the lite-youtube-embed library for the same YouTube video as before – JavaScript in 100 Seconds by Fireship – it weights in at 27.28 kB. That is a fraction of the 1243 kB that the YouTube embed weights in at!

The following resources are downloaded (compressed weights given):

Let’s test what we discussed using WebPageTest to see what it equates to in general performance. Keep in mind that WebPageTest is a lab testing tool and does not accurately portray real-world performance. So, some inaccurate indicators can be reported.

For testing with lite-youtube-embed, I added the script as async so that it is non-blocking. The CSS file and JS file of the library are unminified, I used them as-is. To test the video element, I downloaded the YouTube video using yt-dlp to get the video file.

Test case # Description Test result First Contentful Paint Speed Index Total Blocking Time Page Weight
1 YouTube embed result 1.268S 1.300S 2.254S 1,130KB
2 YouTube embed with native lazy loading result 1.102S 1.106S 2.667S 1,150KB
3 video element with lazy loading result 1.343S 1.400S 0S 77KB
4 Lite YouTube embed result 1.095S 1.106S 0S 78KB

Using native lazy loading on the YouTube embed iframe does not defer loading of the embed’s assets. Whatever the code for the embed does, it appears to force downloading the assets anyway.

<!--native lazy loading of YouTube embed does nothing -->
<iframe width="560" height="315"
src="https://www.youtube.com/embed/DHjqpvDnNGE?si=9vMN2-IImNFOC3Of"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen
loading="lazy">
</iframe>

In fact, if you test a page with a native lazy loaded YouTube embed on Google’s PageSpeed Insights, it suggests using a “facade” to defer third-party resources i.e. use youtube lite! It’s so strange! 👽

PageSpeed Insights feedback on YouTube embed with lazy loading is to : Consider replacing them with a facade until they are required.

There is a big improvement in peformance when you use the video element with lazy loading or youtube-lite-embed– they both have zero total blocking time and the page weighs far less. This is going enable the page to be interacted with immediately.

The test results do not cover the performance of the playback of the video. The video element is the most performant of the 3 because it does not involve downloading assets other than the video file when you hit the play button.

Further optimizations

The preview image used by the video element and lite-youtube-embed are eagerly loaded. You could tweak your set-up to lazy load it too. If you are using a lazy loading library for components or islands in your stack anyway, you could include it and save some extra kB.

A note on privacy

The lite-youtube-embed library uses the youtube-nocookie.com domain instead of youtube.com which is better for the end user’s privacy. However, it does add preload links for google ads to the head too e.g. <link rel="preconnect" href="https://googleads.g.doubleclick.net">. Just keep in mind that YouTube does adtech-y things in general. So, you have to accept that as part of the deal when you use any YouTube in any guise.

Conclusion

I would urge you to rethink embedding YouTube videos in general. Perhaps you don’t need to embed the video in your page, a link may suffice. If an embeded video is the suitable choice, using a video element with “native lazy loading” – add preload="none" and the poster attribute to the element – this is the best experience in town. No crud is loaded in advance. When the user hits play - the only resource downloaded is the actual video. Zero adware.

If you’re going to embed a YouTube video, use the lite-youtube-embed library. Its embed is many, many times smaller than using a YouTube embed – approxmiately 28 kB versus 1243 kB. The difference in performance is vast.

Don’t use the default YouTube embed unless you really have to!

Tagged