Make Your YouTube Embeds Load Faster and Display Responsively

TL;DR - This guide explains how to stop YouTube slowing your pages down by only loading the video thumbnail image unless a user clicks on the video. We've provided the relevant HTML and CSS below, or you can just use our awesome free optimised YouTube embed code generator tool: Free YouTube optimisation tool

As most people already know, you can embed any YouTube video into your website or blog post quite easily, merely taking the link YouTube provides you with and adding it to a HTML body. A huge price is paid from this process despite it's ease of use. This is because it adds a lot of weight to the page, this in turn slows down your loading time for your site and it's performance overall. Unfortunately the YouTube embed code isn't responsive, this may require more work to make it so.

A lot of people add high resolution images without caring about the resources they consume and will add videos one after another without a second thought. This diminishes the potency of a site whose primary focus is to retain users.

Does page speed really matter that much? Absolutely!

When a browser loads a web page, JavaScript and CSS resources usually prevent the web page from being displayed until they are downloaded and processed by the browser. This is known as render blocking, most of the processing is done on one particular resource, for this case YouTube JavaScript. This stops other resources being loaded in that are more essential to a page. The longer a page takes to load the more likely someone will leave before it's loaded.

"Latency matters. Amazon found every 100ms of latency cost them 1% in sales. Google found an extra .5 seconds in search page generation time dropped traffic by 20%. A broker could lose $4 million in revenues per millisecond if their electronic trading platform is 5 milliseconds behind the competition." - Reference

The impact on your website might not be as direct and in such huge proportion, however it definitely affect the amount of users retained on the site.

Page load has a huge impact on bounce rates which is likeliness users will go away from the site and if the impact is that big they may never use it again knowing it's slow.

How to make embedded YouTube videos faster

The YouTube embed downloads half a megabyte of JavaScript files to render the video, one of the issues is that this is downloaded even if the user doesn't play the embedded video. This can be detrimental to a page's performance especially on 3G which is still a lot of mobile users, the video also may not resize properly on mobile.

A smart technique to solving this and the one we will be using is as an alternative it uses the thumbnail image of a YouTube video instead and only loads the video when a user clicks on it.

YouTube thumbnails are normally quite small in size at around 18 kilobytes in size or higher if you use a higher definition thumbnail, which reduces the previous half a megabyte to almost nothing. This is what it would look like which is exactly like any other site embedding the heavy default YouTube video. It is also possible to lazyload those images with a lazyloading tool like lazysizes.

This is what the finished product will look like:

One of the best parts is that it looks exactly like a normal YouTube video with hover styling changing the colour and size of the YouTube button as it should. The way this works is that when a user interacts with the image, it gets replaced with the default YouTube video player. Meaning that those resources mentioned earlier aren't loaded in and processed by the browser until someone presses that video, which means it could not be loaded EVER and that's a huge improvement to site performance.

A bit of structure

Let's start with the HTML as all you will need is a couple of lines of code per YouTube video. Another important thing to consider is noscript functionality, keeping the embedded video in there would be a good option but YouTube doesn't work without JavaScript so you would still get an error.

<!DOCTYPE html>  
<html>  
    <head>
        <title>YouTube Player</title>
        <link rel="stylesheet" type="text/css" href="styles.css">
    </head>
    <body>
        <div class="video">
            <div class="video__youtube" data-youtube>
                <img src="https://i.ytimg.com/vi/VIDEO_ID/maxresdefault.jpg" class="video__placeholder" />
                <button class="video__button" data-youtube-button="https://www.youtube.com/embed/VIDEO_ID"></button>
            </div>
        </div>
    <script src="scripts.js" type="text/javascript"></script>

    </body>
</html>  

The only changes you need to make here are replacing the VIDEO_ID in the YouTube and image links with the particular video you want to use. You can also replace the maxresdefault.jpg with sddefault.jpg if you want even smaller placeholder images, however this does reduce the quality of the image by a lot. A larger issue on desktop than on mobile.

Let's make it pretty

Next up is the beloved CSS which is much longer but no changes need to be made here, I've set the overall width of the video to only be about half the page but you can change it fit a parent component.

.video {
    position: relative;
    width: 50vw;
}

.video__iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

.video__placeholder {
    width: 100%;
    position: absolute;
}

.video__youtube {
    padding-bottom: 56.23%;
    width: 100%;
    height: 0;
    overflow: hidden;
    position: relative;
    object-fit: cover;
    background-color: black;
}

.video__button {
    background: none;
    border: 0;
    cursor: pointer;
    height: 100%;
    left: 0;
    position: absolute;
    text-indent: -9999px;
    top: 0;
    transition: transform 300ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
    width: 100%;
}

.video__button:before {
    width:100%;
    height:100%;
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    background: url(youtube-play-dark.svg) no-repeat center center;
    background-size: 10%; 
}

.video__button:hover:before {
    background: url(youtube-play-red.svg) no-repeat center center;
    background-size: 10%; 
}

A key pointer is that i'm using some .svgs from the YouTube branding site but you can use .png files from the branding site instead. This is an extra as it isn't any functionality but adds to the usability and familiarity for users as it looks like an actual YouTube video especially with the hover styles. The button covers the entire image just like a current video.

Throw some functionality into the mix

I've written the code as an IIFE (Immediately Invoked Function Expression) and also done so using just JavaScript, this simplifies things a little as we don't need any tools like JQuery. This will replace all YouTube videos on a page with the correct markup with their respective placeholder images. The video has been given ?autoplay=1 which makes it autoplay on desktop just as it should however mobile still requires two clicks. The placeholder image is then replaced with the video of the same size.

(function (window) {

    'use strict';

    window.code = window.code || {};

    window.code.lightweightYoutubePlayer = function () {

        var dataYoutubeVideos = '[data-youtube]';

        var youtubeVideos = [...document.querySelectorAll(dataYoutubeVideos)];

        function init() {
            youtubeVideos.forEach(function(element) {
                bindYoutubeVideoEvent(element);
            });
        }

        function bindYoutubeVideoEvent(element) {
            var button = element.querySelector('[data-youtube-button]');

            button.addEventListener('click', createIframe);
        }

        function createIframe(event) {
            var url = event.target.dataset.youtubeButton;
            var youtubePlaceholder = event.target.parentNode;

            var htmlString = '<div class="video__youtube"> <iframe class="video__iframe" src="' + url + '?autoplay=1" frameborder="0" allowfullscreen></iframe></div>';

            youtubePlaceholder.style.display = 'none';
            youtubePlaceholder.insertAdjacentHTML('beforebegin', htmlString);
            youtubePlaceholder.parentNode.removeChild(youtubePlaceholder);
        }

        return {
           init: init
        }
    };

})(window)

ready();

function ready() {  
    var lightweightYoutubePlayer = new code.lightweightYoutubePlayer()

    if (document.readyState != 'loading') {
        page.init()
    } else {
        document.addEventListener('DOMContentLoaded', lightweightYoutubePlayer.init);
    }
}

And that's all you need, enjoy making your websites faster, below is a CodePen with the provided code so you can play around with it.

CodePen


Try our free YouTube optimisation tool

Free YouTube optimisation tool