embed fast thumbnail hero image embed fast
August 21, 2021

How To Load Embedded YouTube Videos Dramatically Faster (With Code)

The YouTube embed code loads 700KB of data and 6+ JavaScript files. And those JavaScript files take a couple seconds to render on a mobile device. Worse, those scripts also add tracking cookies for every visitor automatically.

This is unacceptable when you want a fast blog that can pass core web vitals. In fact, I saw large traffic decreases when I started embedding a lot of YouTube videos on this blog. Particularly with International traffic using slow Internet connections.

So I wrote this blog post documenting how to lazy-load a YouTube video. This code will only load the thumbnail image. Saving you 2-3 seconds of load time (or more) on a mobile device.

What The End Result Looks Like!

I’ve already implemented this code on my blog. Here’s what it looks like when finished. Very similar to a regular YouTube player!

The HTML

The HTML needed to be simple so that bloggers with no technical skills could use it. And thankfully it is! Just replace the YouTube video id in the HTML below and your video will load!


//replace the data-embed attribute with your YouTube video ID (can be found in normal embed code)  
<div class="youtube"  data-embed="lA9ezip8UrE" > </div>

The CSS

Most of the CSS needed to make this work was for the play button. But, you should be able to easily copy/paste this onto your site and have it work (unless you have name conflicts).


.youtube:hover{
  cursor: pointer;
  .play {
    background: red;
    opacity: 0.9;
  }
}

.play {
  font-size: 1.1em; /* change this to change size */
  transform: translateY(130px);
  position: absolute;
  left:0;
  right:0;
  margin:auto;
  background: #3b3636;
  opacity: 0.75;
  border-radius: 50% / 10%;
  color: #FFFFFF;
  height: 3em;
  padding: 0;
  text-align: center;
  text-indent: 0.1em;
  transition: all 150ms ease-out;
  width: 4em;
}

.play::before {
  background: inherit;
  border-radius: 5% / 50%;
  bottom: 9%;
  content: "";
  left: -5%;
  position: absolute;
  right: -5%;
  top: 9%;
}

.play::after {
  border-style: solid;
  border-width: 1em 0 1em 1.732em;
  border-color: transparent transparent transparent rgba(255, 255, 255, 0.75);
  content: ' ';
  font-size: 0.75em;
  height: 0;
  margin: -1em 0 0 -0.75em;
  top: 50%;
  position: absolute;
  width: 0;
}

The JavaScript

There are only two downsides to using this script.

  1. The image won’t load until after your JavaScript renders. So there will be slight delay on loading them compared to other images. Shouldn’t be a big deal.
  2. When you click the video there will be a delay (as you now need to load 700k worth of files to run the video).

Other than that this code is simple and works like a dream. You should be able to copy and paste it into your scripts somewhere.


     
document.addEventListener("DOMContentLoaded", function(event) {


        //Load YouTube Videos on page...
        var youTubeVideos = document.querySelectorAll('.youtube');
        for (var i = 0; i < youTubeVideos.length; i++) {
            var thumbnail = "https://img.youtube.com/vi/"+ youTubeVideos[i].dataset.embed +"/maxresdefault.jpg";
            //set CSS
            youTubeVideos[i].style.cssText = "max-width: 560px;margin: 60px auto;";

            //set microdata attributes for SEO
            youTubeVideos[i].setAttribute("itemprop", "video");
            youTubeVideos[i].setAttribute("itemscope", '');
            youTubeVideos[i].setAttribute("itemtype", "http://schema.org/VideoObject");

            //set HTML
            youTubeVideos[i].innerHTML = '<div class="play"></div>' +
                '<meta itemprop="embedURL" content="https://www.youtube.com/embed/' +  youTubeVideos[i].dataset.embed +'" />' +
                '<img style="cursor: pointer;" width="560" height="315" src="' + thumbnail + '" />';

            //add click event that will load YouTube video
            youTubeVideos[i].addEventListener( "click", function() {
                this.innerHTML = '<iframe width="560" height="315" frameBorder="0" ' +
                    'allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"' +
                    'src="https://www.youtube.com/embed/' + this.dataset.embed + '?enablejsapi=1&rel=0&showinfo=0&autoplay=1"' +
                    ' allowFullScreen="allowfullscreen"></iframe>';
            } );

        }

}

YouTube Thumbnail Size Options

I used the largest thumbnail option available in the code above. I did so because the other 16:9 options were too small. If you decide to use a 4:3 option it will have annoying black bars on the top and bottom of the image. This will require you to do extra CSS work to remove the bars.

However, you should know about the other YouTube thumbnail options in case you want to make this even more lightweight than it already is. To change the file size, you’d simply alter the image tag in the JavaScript above from maxresdefault.jpg to namefromtable.jpg. Very easy!

Name Size Aspect Ratio Black Bars?
maxresdefault.jpg 1280×720 16:9 No
mqdefault.jpg 320×180 16:9 No
sddefault.jpg 640×480 4:3 Yes
hqdefault.jpg 480×360 4:3 Yes
default.jpg 120×90 4:3 Yes

Note: If you change the name to 1.jpg, 2.jpg, or 3.jpg, it will grab the autogenerated YouTube thumbnails in the default size.

Will This Hurt SEO?

Improving your load time by a couple of seconds will improve SEO and user experience.

That said, we don’t want to confuse Google and have them not realize that we have a video in our post. Videos can drive a lot of clicks through Google Video Search.

One way to solve this would be to add Schema.org to your blog posts. But, to make it easier than that, I simply added microdata in the JavaScript above. Meaning you don’t have to do anything, Google should recognize that you have a video in your post still!

Here’s an example of what the resulting HTML looks like after our JavaScript runs. Notice the meta tag noting the video URL. This should give Google what it needs to know about this video.


<div class="youtube" data-embed="VSiQCL3oBj8" itemprop="video" itemscope itemtype="http://schema.org/VideoObject" style="max-width: 560px; margin: 60px auto;" >
<div class="play"></div>
<meta itemprop="embedURL" content="https://www.youtube.com/embed/VSiQCL3oBj8">
<img style="cursor: pointer;" width="560" height="315" src="https://img.youtube.com/vi/VSiQCL3oBj8/maxresdefault.jpg">
</div>


So all page speed gains with no SEO downside at all. You’re welcome!

Shaun Poore worked as a professional software developer for 15 years before transitioning into content creation and digital product businesses. Shaun's currently focused on providing as many people as possible with actionable advice and tools they can use to succeed online, without the fluff or BS that too often plagues this industry.