Perfect Youtube Core Web Vitals
Learn how to embed youtube video's without losing PageSpeed
Perfect YouTube Core Web Vitals
YouTube video's are a great way to enhance your page. The user experience of added video's is just amazing.
No matter how hard you try, YouTube video's will always slow down the page if you embed them using the default YouTube embed code.
In this short article I will show you how to speed up your page and embed YouTube video's without losing PageSpeed
How to embed a YouTube video (the slow way)
YouTube has made it pretty simple to embed a video on your page. First navigate to the video page and click on share below the video
Next select embed and copy the embed code:
Copy the code and paste it into the HTML of your site. When you then run a lighthouse audit you will notice that all the important metrics like First Contentful Paint, Speed index, Largest Contentful Paint and the Time to interactive have increased by about 1 - 1.5 seconds. Lets fix this:
Default YouTube embed
Smart YouTube embed
Fix the YouTube Core Web Vitals!
We are going to fix the Core Web Vitals by creating a placeholder for the image. During page load the placeholder will be loaded. Only when we actually need the YouTube video will we change the placeholder for the actual video.
Step 1: Download the placeholder image
Downloading the placeholder image is real easy. Look at the url for the YouTube video. For this example we will use This url: https://www.youtube.com/watch?v=Oxv6IRcuNaI
As you might notice there is a variable in the url: 'Oxv6IRcuNaI'. Copy that variable and paste it into the default image location for any YouTube video https://i.ytimg.com/vi_webp/Oxv6IRcuNaI/maxresdefault.webp
Open that url, right click the image and select 'save image as'. After you have downloaded the image resize it to you needs.
Step 2: create the placeholder
The next step is to create the placeholder. I am going to use a relative positioned div, place an image with object-fit:cover and an empty i-frame that we will populate later.
<div id="ytplaceholder"> <img class="ytcover" loading="lazy" src="https://i.ytimg.com/vi_webp/Oxv6IRcuNaI/maxresdefault.webp"> <iframe id="ytiframe" data-src="https://www.youtube.com/embed/Oxv6IRcuNaI"> </iframe> </div>
So far so good, now let's add some styling. The padding in the YouTube placeholder is a little trick to ensure the video scales on all devices. The image is placed absolute at the top and has an object-fit:absolute property. This mimics a background image but allows for lazy loading and responsive images. Finally the iframe itself has an absolute position and covers the entire placeholder once it is visible.
#ytplaceholder {
position: relative;
position: relative;
overflow: hidden;
padding-top: 56.25%;
}
#ytplaceholder img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
object-fit: cover
}
#ytplaceholder iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
opacity: 0;
transition: opacity 2.4s ease 0s;
}
Now for the magic: let's change the placeholder image to an actual video. I add an event listener to the YouTube placeholder. Once a visitor hovers over the image the YouTube i-frame loads and becomes visible because of the opacity change.
<script> // youtube placeholder var ytplaceholder = document.getElementById ('ytplaceholder'); // change the video var videolistner = function(e) { var ytiframe = document.getElementById('ytiframe'); ytiframe.src = ytiframe.getAttribute('data-src'); ytiframe.onload = ytiframe.style.opacity = 1; ytplaceholder.removeEventListener("mouseover", videolistner); }; //listen to the mouseover event to change the video ytplaceholder.addEventListener('mouseover', videolistner);
Always show the YouTube video
Lets go one step further and queue the YouTube video to always replace the placeholder image even without any interaction. I do not want to do that right away, let's wait until the browser is idle. I'll use a time-out for simplicity but the requestIdleCallback() method would be great choice as well
<script> var ytplaceholder = document.getElementById ('ytplaceholder'); var videolistner = function (e) { var ytiframe = document.getElementById ('ytiframe'); ytiframe.src = ytiframe.getAttribute ('data-src'); ytiframe.onload = ytiframe.style.opacity=1; ytplaceholder.removeEventListener ("mouseover", videolistner); }; ytplaceholder.addEventListener ('mouseover', videolistner); // show the YouTube video anyway after 3 seconds setTimeout(function(){ videolistner(); },3000); </script>
Here you go guys, a perfect page-speed score with an embedded YouTube video in just a few lines of code.
Extend this technique.
Of-course this is just a simple example that only works for a single YouTube video with a specific id. On your site it would be a good idea to attach the event listener to a querySelector and also attach the interaction-observer to automatically load YouTube video's before they scroll into view. However you want to extend it: the idea stays the same!
Stop Guessing, Start Measuring
I use Core/Dash to optimize my clients sites. So Should You.
- Easy set up.
- Over 5000 happy clients
- Free trial, No strings attached