Lazy load Youtube Video Iframe


How to prevent loading youtube video iframe & related files until the user clicks to play the video.

Why not directly add youtube video iframe snippet?

Youtube’s iframe snippet brings ~500 KB (gzipped) worth of files with it. Around 85% of this is JavaScript. This will cause your video thumbnail display to be slower (look here). On mobile networks & devices, it shall also adversely affect the speed of loading other parts of the page.

Not every visitor to your page will play the youtube video. As a result, it is optimal to load the youtube video iframe files when the user clicks the play button. This how-to provides steps to do so. For the sake of this how-to, let’s assume below is your youtube iframe snippet:

<iframe style="max-width:100%" width="560" height="315" src="https://www.youtube.com/embed/e1gAyQuIFQo" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Changing the iframe snippet to not load any files

An easy way to prevent the iframe snippet from loading files is to:

  • Specify the iframe’s source as ‘data-src’.
  • Add class & id to iframe to help JavaScript refer to it later.
  • Add display:none to hide it initially.

<iframe style="max-width:100%;display:none;" id="youtube-embed-iframe" width="560" height="315" data-src="https://www.youtube.com/embed/e1gAyQuIFQo" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Setting up the preview thumbnail

A simple way to extract the preview thumbnail for your youtube video is to use the following URL pattern https://img.youtube.com/vi/{video-id}/mqdefault.jpg. We need to set this image as a hyperlink to load the youtube video and also have a ‘Play’ button on top of it. The below snippet does so:

<style>
.youtube {
    position: relative;
    display: inline-block;
}
.youtube:before {
    content: "";
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 10;
    background-size: 30%;
    background: transparent url('url_for_play_button.svg') center center no-repeat;
}
</style>
<a href="javascript:void(0);" onclick="showVideo();" id="youtube-link" class="youtube" >
	<img id="youtube-thumb" src="https://img.youtube.com/vi/e1gAyQuIFQo/mqdefault.jpg" width="560" style="max-width:100%" alt="{ video title }" />
</a>

With the above code snippet, we are yet to specify how to load the youtube video on clicking the above link (via showVideo() function).

Loading & playing Youtube video on thumbnail click

Below JavaScript defines showVideo(). This function:

  • Hides the thumbnail
  • Shows Youtube iframe & sets it’s src attribute
  • Loads Youtube ifram api, which we use to auto-play the video on loading

<script>
var player;
function onYouTubeIframeAPIReady() {
    player = new YT.Player('youtube-embed-iframe', {
      height: '315',
      width: '560',
      videoId: 'e1gAyQuIFQo',
      events: {
        'onReady': onPlayerReady,
      }
    });
}

function onPlayerReady(event) {
        console.log('player ready');
    event.target.playVideo();
}


function stopVideo() {
    player.stopVideo();
}

function showVideo()
{
        document.getElementById('youtube-link').style.display = "none";
        document.getElementById('youtube-embed-iframe').style.display="block";
        document.getElementById('youtube-thumb').style.display="none";
        let ifr = document.getElementById('youtube-embed-iframe');
        ifr.setAttribute('src',ifr.getAttribute('data-src'))
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
</script>

Bringing it all together

Here’s a CodePen that brings into action all of the above listed code snippets for you to explore further.