DEV Community

Cover image for Improve Speed with Lazy-Loaded Youtube Videos (+Autoplay)
aryaziai
aryaziai

Posted on • Edited on

Improve Speed with Lazy-Loaded Youtube Videos (+Autoplay)

There is something addicting about webpage speed tests. I typically use PageSpeed Insights and GTMetrix to measure a website's performance upon completion. However, there is a thin line between a quick loading webpage and not compromising any important features. I recently found myself in a tricky position after testing out a blog site I created which primarily consisted of youtube videos. The site contains hundreds of posts, and each post contains a specific youtube video. When the user views a post, the video within the post begins auto-playing (thanks to the "?autoplay=1" parameter appended to the youtube link). Unfortunately this behavior drastically increases the load time with many requests needing to be made for resources.

I'll be using GTMetrix to draw speed comparisons since it provides us with a more detailed break-down than PageSpeed Insights by Google.

It took 4.8 seconds to fully load the page and 44 requests. As you can see below, a majority of these requests are being made by the embedded youtube code.

After researching this issue, I found Arthur Corenzan on dev.to provide a very clever solution. By embedding the link inside the srcdoc attribute, the user will only need to download the cover image for the video. Once the image is clicked, the youtube video will load.


The first modification I made was by replacing the ▶ button with the official youtube play icon and styling it to appear in the middle of the cover image. Although the iframe code resolved my speed issue, it required the user to click the cover image for the video to begin playing. I fixed this by adding a script to the footer of my post which automatically clicks the cover-image once the page is loaded. If you're not interested in auto-playing the video, please ignore the function below.

window.onload = function () {
setTimeout(function () {
document.querySelector('#videoframe').contentDocument.querySelector('#playbutton').click();
  }, 2000);
};

You can change the value to a number below 2000 but be cautious. If the video is auto-clicked before the page has finished loading, then we are back to square one (if anyone has a better solution please share).

Below is my final iframe code:

<iframe
  width="100%"
  height="100%"
  id="videoframe"
  srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{background:#000;height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}</style>
  <a href=https://www.youtube-nocookie.com/embed/YOUTUBE_VIDEO_ID?autoplay=1&modestbranding=1&iv_load_policy=3&theme=light&playsinline=1>
  <img src=https://img.youtube.com/vi/YOUTUBE_VIDEO_ID/hqdefault.jpg>
  <img id='playbutton' src='YOUTUBE_PLAY_BUTTON_IMAGE_URL' style='width: 66px; position: absolute; left: 41.5%;'></a>"
  frameborder="0"
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  scrolling="no" 
  loading="lazy"
 style="background-color: #000" 
></iframe>

I've shared the youtube play icon here, feel free to download it and host it on your own server. I'm also using the hqdefault version of the youtube video thumbnail. You can try maxresdefault if you want a higher quality image but not every video has a maxresdefault image. You can use this tool to see which image versions of the video are available.

Now let's test the page speed with the new iframe code:

We've drastically cut down the load time and the requests! The user won't notice anything different and the video is still auto-playing as it was before we implemented the new iframe code. If the user manages to click the play button before the script does, the video will still play without any issues.

Final result:

Top comments (1)

Collapse
 
si25 profile image
Simon Gibbs • Edited

Nice one, great post

Found you can centre the play button better with

left: 50%;
transform: translateX(-50%);

You also need to tweak the code on this line to get the autoplay to work onclick
allow="accelerometer; autoplay *; encrypted-media; gyroscope; picture-in-picture"