Currently, if I put into a website some video via iframe code and use autoplay mode, I always get a very bad score on Google Pages Speed Insights. I found only one way to avoid the problem. It is lazy loading a video after 4 seconds delay. However, the described method is not good for user experience. Does somebody know a more appropriate way to fix that?
-
dupe of https://stackoverflow.com/questions/50410828/how-to-prevent-youtube-js-calls-from-slowing-down-page-load – giorgio79 Jan 02 '22 at 16:03
2 Answers
The best way to do this is to show an image instead (ideally the thumbnail but there is no reason why you couldn't show a different image) and load the video and all the related JS when the image is clicked.
The below method is just an example of how to do this, in production it would be better to actually load it properly using the YouTube API so the video plays on click instead of having to click twice, (they disabled autoplay for videos with sound using iFrame embedding) but it should give you a good starting point as your question was simply how to get around the problem!
Please note that due to restrictions on Stack Overflow the below video won't play, here is a jsFiddle here that works. with exactly the same code as below.
( function() {
var youtube = document.querySelectorAll( ".youtube" );
for (var i = 0; i < youtube.length; i++) {
var source = "https://img.youtube.com/vi/"+ youtube[i].dataset.embed +"/sddefault.jpg";
var image = new Image();
image.src = source;
image.addEventListener( "load", function() {
youtube[ i ].appendChild( image );
}( i ) );
youtube[i].addEventListener( "click", function() {
var iframe = document.createElement( "iframe" );
iframe.setAttribute( "frameborder", "0" );
iframe.setAttribute( "allowfullscreen", "" );
iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&showinfo=0&autoplay=1" );
this.innerHTML = "";
this.appendChild( iframe );
} );
};
} )();
html {
background-color: #f3f3f3;
}
.wrapper {
max-width: 680px;
margin: 60px auto;
padding: 0 20px;
}
.youtube {
background-color: #000;
margin-bottom: 30px;
position: relative;
padding-top: 56.25%;
overflow: hidden;
cursor: pointer;
}
.youtube img {
width: 100%;
top: -16.82%;
left: 0;
opacity: 0.7;
}
.youtube .play-button {
width: 90px;
height: 60px;
background-color: #333;
box-shadow: 0 0 30px rgba( 0,0,0,0.6 );
z-index: 1;
opacity: 0.8;
border-radius: 6px;
}
.youtube .play-button:before {
content: "";
border-style: solid;
border-width: 15px 0 15px 26.0px;
border-color: transparent transparent transparent #fff;
}
.youtube img,
.youtube .play-button {
cursor: pointer;
}
.youtube img,
.youtube iframe,
.youtube .play-button,
.youtube .play-button:before {
position: absolute;
}
.youtube .play-button,
.youtube .play-button:before {
top: 50%;
left: 50%;
transform: translate3d( -50%, -50%, 0 );
}
.youtube iframe {
height: 100%;
width: 100%;
top: 0;
left: 0;
}
<div class="wrapper">
<div class="youtube" data-embed="U9t-slLl30E">
<div class="play-button"></div>
</div>
</div>

- 22,724
- 2
- 32
- 64
LazyLoad is kind enough to do the job. The plugin does not only apply lazy load to images, but also to embed videos and Iframes. Just set it up and apply "lazy" as a class to the YouTube iframe.
Here is a quick example:
<script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.3.1/dist/lazyload.min.js"></script>
<script>var lazyLoadInstance = new LazyLoad();</script>
<iframe class="lazy" height="300" width="500" data-src="https://www.youtube.com/embed/YoutubeCode"></iframe>

- 181
- 5