On-Demand Embedded Videos

Page Speed Checklist

Reduce Initial-Load Page Weight With On-Demand Videos

Reduce initial-load page weight by only loading embedded video resources on-demand.

Embedded videos from 3rd-party platforms like Vimeo and YouTube are a great way to include videos directly on a webpage, but can add more than 500KB of page weight even when they're not played. This technique replaces a placeholder image and link to the video with the embedded video when clicked. The image and link doubles as a perfect no-JavaScript fallback.

An on-demand embedded video in action:

The HTML

Start with a link and thumbnail image, wrapped in a container with the video ID stored as a data attribute.

HTML
<div class="video" data-videoid="VIDEO ID">
    <a href="https://www.youtube.com/watch?v=VIDEO ID" target="_blank" rel="noreferrer nofollow">
        <img src="https://img.youtube.com/vi/VIDEO ID/sddefault.jpg" width="WIDTH" height="HEIGHT" alt="VIDEO TITLE" loading="lazy">
    </a>
</div>

The CSS

Style the placeholder image link as desired, including a custom play button. This setup also uses a technique for responsive embedded videos that scale with a custom aspect ratio.

CSS
.video {display:block;padding-bottom:56.25%;background-color:#111;box-shadow:0 0 0 1px #f9f9f9, 0 0 0 2px #ccc;position:relative;margin:0 0 1.5rem;overflow:hidden} /*--- bottom (or top) padding sets aspect ratio ---*/

        /*--- iframe (when loaded) ---*/
        .video iframe {border:0;position:absolute;width:100%;height:100%}

        /*--- placeholder link ---*/
        .video a {display:block}

            /*--- play button ---*/
            .video a::before {box-sizing:border-box;display:block;height:1em;width:1em;background-color:rgba(0,0,0,0.6);border:.05em solid #fff;border-radius:50%;box-shadow:0 0 0.15em 0 rgba(0,0,0,0.6);position:absolute;top:50%;left:50%;z-index:1;font-size:3em;margin:-.5em 0 0 -.5em;transition:background-color .2s;content:""}
            .video a:hover::before, .video a:focus::before {background-color:#2b9a27}
            	.video a::after {display:block;width:0;height:0;border:0 solid transparent;border-width:.2em 0 .2em .3em;border-left-color:#fff;position:absolute;top:50%;left:50%;z-index:1;font-size:3em;margin:-.2em 0 0 -.1em;content:""}

            /*--- preview image ---*/
            .video img {display:block;position:absolute;top:-16.82%;width:100%}
    }

The JavaScript

Replace the image link with a normal embedded video <iframe> when the placeholder is clicked.

JavaScript
// select all .video elements
var videos = document.querySelectorAll('.video');

for (var i = 0; i < videos.length; i++) {
    videos[i].addEventListener('click', function() {
        var iframe = document.createElement('iframe');
        iframe.setAttribute('allowfullscreen', 'allowfullscreen');
        iframe.setAttribute('src', 'https://www.youtube.com/embed/'+ this.dataset.videoid +'?autoplay=1');
        iframe.setAttribute('allow', 'autoplay');
        this.innerHTML = '';
        this.appendChild(iframe);
        event.preventDefault();
    });
};

Minified:

JavaScript
var videos = document.querySelectorAll('.video'); for (var i = 0; i < videos.length; i++) { videos[i].addEventListener('click', function() { var iframe = document.createElement('iframe'); iframe.setAttribute('allowfullscreen', 'allowfullscreen'); iframe.setAttribute('src', 'https://www.youtube.com/embed/'+ this.dataset.videoid +'?autoplay=1'); iframe.setAttribute('allow', 'autoplay'); this.innerHTML = ''; this.appendChild(iframe); event.preventDefault(); }); };

Without JavaScript

This sans-JavaScript alternative is more limited in features and browser support, but similarly avoids loading the full embedded video resources until the user clicks the play button. The srcdoc attribute supersedes the regular src attribute in browsers that support it.

HTML
<div class="video">
    <iframe src="https://www.youtube.com/embed/VIDEO ID?rel=0&autoplay=1" srcdoc="<style>*{display:block;padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:-1px;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.2em black}</style><a href='https://www.youtube.com/embed/VIDEO ID?rel=0&autoplay=1'><img src='https://img.youtube.com/vi/VIDEO ID/sddefault.jpg' alt='Video Title Goes Here' loading='lazy'><span>▶</span></a>" allow="autoplay" allowfullscreen title="Video Title Goes Here" loading="lazy"></iframe>
</div>

Responsive Embedded Videos

This technique works great when combined with mobile friendly, automatically-scaling embedded videos:

Responsive Embedded Videos