<html> <head><title>Embedded YouTube Video</title></head> <body> <iframe width="1280" height="720" src="https://www.youtube.com/embed/ck7utXYcZng" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen> </iframe> </body> </html>
Embedding YouTube videos without making your site fatter
Making this site lighter and improving load times for my readers has been a priority for some years. I’ve stopped embedding web fonts, I’ve started using Unicode icons instead of relying on Font Awesome and I’ve also started loading Disqus comments on demand, which also has a positive impact on the privacy of anyone reading these pages.
However, on a few occasions I’ve wanted to embed a YouTube video in one of the posts, and I had never realized this can heavily impact page sizes and load times. Take, for example, the following HTML document.
The iframe
code you see above is almost verbatim copied from the code YouTube
gives you when you right-click on the video and select “Copy embed code”. If
you store that document locally and try to open it with Firefox using its
network inspection tool, you’ll discover it attempts to load, as of the time
this text is being written, around 1.84MB of data, and that’s with
uBlock Origin blocking some additional
requests. The largest piece of that being YouTube’s base Javascript library.
On the one hand, it’s likely many people already have that file, and some
others, in their browser cache. On the other hand, I don’t feel comfortable
making that assumption and throwing my hands up. This prompted me to try to
find a way to embed YouTube videos without adding so much data by default, and
it turns out
other people
have found solutions to the problem, which I’ve slightly tuned and I’m
re-sharing here. Instead of using the previous iframe
code, I use something
slightly more convoluted.
<html> <head><title>Embedded YouTube Video</title></head> <body> <iframe title="Video: Why Can't You Download Videos on YouTube? How a 20-Year-Old Law Stops youtube-dl Users AND Farmers" height="720" width="1280" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen src="https://www.youtube.com/embed/ck7utXYcZng" srcdoc=" <style> * { padding: 0; margin: 0; overflow: hidden; } html, body { height: 100%; } img, span { /* All elements take the whole iframe width and are vertically centered. */ position: absolute; width: 100%; top: 0; bottom: 0; margin: auto; } span { /* This mostly applies to the play button. */ height: 1.5em; text-align: center; font-family: sans-serif; font-size: 500%; color: white; } </style> <!-- The whole frame is a link to the proper embedded page with autoplay. --> <a href='https://www.youtube.com/embed/ck7utXYcZng?autoplay=1'> <img src='https://img.youtube.com/vi/ck7utXYcZng/hqdefault.jpg' alt='Video: Why Cant You Download Videos on YouTube? How a 20-Year-Old Law Stops youtube-dl Users AND Farmers' > <!-- Darken preview image laying this on top. Also makes the play icon stand out. --> <span style='height: 100%; background: black; opacity: 75%'></span> <!-- Play icon. --> <span>▶</span> </a>" ></iframe> </body> </html>
The first few lines are almost identical up to the src
property. I’ve only
added the title
property for accessibility reasons. Special care needs to be
taken if the video title contains double quotes or single quotes. The src
property contains the classic URL but it’s only used as a fallback for browsers
that do not support the srcdoc
property that starts on the next line.
srcdoc
allows you to specify an inline document that will be used instead of
loading the frame from an external URL. Support for it is widespread nowadays.
As you can see, the embedded inline document contains a style
element
followed by an a
element pointing to the real embedded iframe
, only this
time with the autoplay
parameter set to 1, so the video will immediately
start playing when the frame is loaded.
The provided style sheet makes sure the link fills the entire embedded
iframe
, so clicking anywhere on it loads the video and starts playing it.
Inside the link you’ll find 3 items. The first one is the video thumbnail in
YouTube’s “high quality” version, which is actually lightweight and gets the
job done as the background image. My guess is the name predates HD and FHD
content. On top of that image I’ve placed a span
element with a black
background color and 75% opacity that, again, fills the whole iframe
and
darkens the background image, making the play button stand out. Finally,
another span
element is laid out on top of those, containing the Unicode
character for a triangle pointing to the right in a large font. This serves as
the aforementioned play button and gives readers the visual clue they need to
click on the video to start playing it.
With those changes and for this particular video, the browser only needs to load around 9KB of data. You can see what it looks like below.
Edit 2020-12-08: The autoplay
parameter is ignored by YouTube on mobile and
users will need to tap twice to watch the video: once to click on your link and
load the iframe
and once more to start playing the video from it. Still, I
think double tapping is worth saving almost 2MB by default. On an iPad I only
need to tap once, so it depends on the exact device and what’s considered
“mobile”.