Zach’s ugly mug (his face) Zach Leat­herman

One YouTube Embed weighs almost 1.2 MB

A grid of 6×5 YouTube logos, each with a slightly different rotation
2k 10 December 11, 2023

The default YouTube embed is… well… atrocious (sorry). Consider an embed for this sample video:

  • 1149 kB total weight, including:
  • 971 kB JavaScript
  • 61 kB Poster Image (jpeg, 1280×720)
  • 48 kB CSS
  • 41 kB of iframed HTML
  • 28 kB for ×3 Roboto Web Fonts

(compressed wire weights reported)

This, uh, conspicuously—does not include any preloading of video content.

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).

A better solution

Instead of the above, I typically use Paul Irish’s lite-youtube web component for better YouTube embeds on my site. The results speak for themselves: the entirety of this blog post weighs a grand total of 229 kB (and that includes the demo YouTube embed below)—just 17% of the original YouTube embed.

Even better, <lite-youtube> is a web component which means it can be managed with <is-land>.

If you look at just the weight of <lite-youtube>:

  • 31 kB total weight, including:
  • 6 kB JavaScript
  • 3 kB CSS
  • 22 kB Poster Image

This is a huge improvement: a reduction of 1149 kB to 31 kB.

Higher quality posters

<lite-youtube> does provide an eagerly loaded JavaScript-only 480×360 poster background-image for you (usually ~20–30kB). This behavior is skipped if you’ve added your own background-image in a style attribute on the tag.

This works fine but I wanted my poster images to be a bit higher quality and I used the 11ty OpenGraph API to easily accomplish this. I pointed the background-image property to the API and required a JPEG format in the output, which seemed to average about 80–100kB each, instead (and didn’t require JavaScript).

<lite-youtube
	videoid="YYJpFdEaAuc"
	style="
		background-image: url('https://v1.opengraph.11ty.dev/https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3DYYJpFdEaAuc/auto/jpeg/');
	"></lite-youtube>

One Weird Trick to Lazy Load the Poster

These components were being managed by <is-land> for lazy initialization and despite the components being lazily initialized the poster images were still being eagerly loaded (before the is-lands were initialized).

Here’s how I fixed it:

is-land[ready] lite-youtube {
	--yt-poster-img-url: var(--yt-poster-img-url-lazy);
}

We are using a double custom property method to work with the existing feature of background-image overrides in lite-youtube:

<lite-youtube
	videoid="YYJpFdEaAuc"
	style="
		--yt-poster-img-url-lazy: url('https://v1.opengraph.11ty.dev/https%3A%2F%2Fyoutube.com%2Fwatch%3Fv%3DYYJpFdEaAuc/auto/jpeg/');
		background-image: var(--yt-poster-img-url);
	"></lite-youtube>

As this is using <is-land> this re-enables the JavaScript dependency for the poster images but I’m okay with that, as I also include a text link to YouTube for each video embed (as part of the WebC component).

You can see all of this in action below:

Watch on YouTube: Partial Hydration and Islands Architecture—Eleventy 🎈 Weekly №12

IndieWeb Avatar for https://unsplash.com/Poster image by Javier Miranda

< Older
is-land Web Component
Newer >
snow-fall Web Component

Zach Leatherman IndieWeb Avatar for https://zachleat.com/is a builder for the web at Font Awesome and the creator of Build Awesome (née IndieWeb Avatar for https://www.11ty.devEleventy/11ty), an award-winning open source website generator. He measures website performance with speedlify and at one point became too fixated on web fonts. He has given 89 talks in nine different countries at events like Beyond Tellerrand, Smashing Conference, Jamstack Conf, CSSConf, and The White House. Formerly part of CloudCannon, Netlify, Filament Group, NEJS CONF, and NebraskaJS. Learn more about Zach »

1 Repost
IndieWeb Avatar for https://www.ricardochavezt.com
Shamelessly plug your related post

These are webmentions via the IndieWeb and webmention.io.

Sharing on social media?

This is what will show up when you share this post on Social Media:

How did you do this? I automated my Open Graph images. (Peer behind the curtain at the test page)