Facebook icon Cross icon Twitter icon Google+ icon RSS icon Skip to Main content Skip to Navigation

Smart video embedding

Why should we even care about this? Can't we just insert the video iframe the old fashioned way and live happily ever after?

But of course, you can! We just want to push things a little further and squeeze every bit for better performance. Few reasons:

  1. We are slowing initial load time. Perhaps the user wants to read a bit from your article and after a while to play the video?
  2. User may not even want to watch the video or intends to watch it later?
  3. You embedded the video with autoplay and sound. User is at work and wild loud kinky sounds appear... not good!
  4. May 2018, GDPR Update: You are setting tons of potentially unwanted cookies. Your users may get upset if they didn't give their consent about Third Party cookies.

In all the situations above we are making unnecessary requests. While with "smart" embedding the requests to video provider are made only when the user hits the "Play" button.

Screenshot of Chrome Dev Tools showing request count with Direct embed technique
Direct Embedding (iframe) - results in 18 requests, 612 KB page size and 720ms load time.
Screenshot of Chrome Dev Tools showing request count with Smart embed technique
Smart Embedding - results in 5 requests, 49.2 KB page size and 33ms load time.

As you can see above "Smart" embedding is the way to go! It is super simple, let me show you!

For the sake of simplicity we will use YouTube in our example, but you can easily modify the functions to support Vimeo and other video providers. There are tons of examples out there.

The HTML

<div class="video">
    <a href="https://www.youtube.com/watch?v=SECVGN4Bsgg" class="video__link js-video" rel="nofollow noopener noreferrer" title="Play" target="_blank">
        <img src="https://img.youtube.com/vi/SECVGN4Bsgg/0.jpg" class="video__thumb" alt=""/>
    </a>
</div>

The .video element serves as container, initially containing only .video__link, which when clicked will be replaced by the iframe itself. This markup allows us to have functional videos even for people with disabled JS, but how? We use preventDefault() below which stops the default behavior of our hyperlink. If JS is disabled the user will simply be redirected to video provider's website in a new window.

The JavaScript

// Sample YouTube parser function. Taken from: https://stackoverflow.com/a/8260383/4509457
function youtubeParser(url){
  var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
  var match = url.match(regExp);
  return (match&&match[7].length==11)? match[7] : false;
}

// Play Video
function playYoutubeVideo(e) {
  const link = this.getAttribute('href');
  const videoId = youtubeParser(link);
  // Video was parsed correctly. Append it. Else the preventDefault() will not fire and user will be redirected to the href attribute location.
  if (videoId) {
    e.preventDefault();

    // Create the iframe
    const iframe = document.createElement('iframe');
    iframe.setAttribute('src', 'https://www.youtube.com/embed/' + videoId + '?autoplay=1');
    iframe.setAttribute('width', 560);
    iframe.setAttribute('height', 315);
    iframe.setAttribute('allow', 'autoplay; encrypted-media');
    iframe.setAttribute('frameborder', 0);

    // Append the iframe
    this.parentElement.appendChild(iframe);

    // Remove the link
    this.remove();
  }
}

// Bind the events
const buttons = document.querySelectorAll('.js-video');
for (let i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', playYoutubeVideo);
}

The code block above has two important parts:

  1. youtubeParser() - extracts the video ID from any YouTube link.
  2. playYoutubeVideo() - if the video ID was extracted successfully, an iframe element is created and appended in the .video parent.
    The ?autoplay=1 parameter allows us to play our video right after the user clicks, mimicking a video player.

View Demo on Codepen


TL;DR: loading content that the user did not request slows your website. The idea of this article can be combined with the Lazy loading pattern depending on your use cases. For example Facebook or Disqus comments can be loaded when user scrolls down to the comments section? Or even clicks on a button named "Load Comments" for example? The opportunities are endless, happy optimizing!


Enjoyed reading?
Share it!


Stay connected