J'utilise https://gtmetrix.com pour diagnostiquer les problèmes liés à la vitesse de ma page.
La page en question contient une vidéo YouTube intégrée et GTMetrix indique que les appels JS de cette vidéo ralentissent la vitesse de chargement de la page.
C'est l'appel qui est fait:
<iframe width="640" height="360" src="https://www.youtube.com/embed/PgcokT0AWHo" frameborder="0" allowfullscreen></iframe>
Voici un exemple d'attribution dynamique de src
au chargement de la page, à l'aide d'une solution JS pure. Utiliser des écouteurs d'événement au lieu de window.onload
car avec ce dernier, un seul événement peut être défini et il remplacerait tout événement précédent window.onload
:
<iframe id="videoFrame" width="640" height="360" src="" frameborder="0" allowfullscreen></iframe>
<script>
function setVideoFrame(){
document.getElementById('videoFrame').src = 'http://example.com/';
}
if (window.addEventListener) // W3C DOM
window.addEventListener('load', setVideoFrame, false);
else if (window.attachEvent) { // IE DOM
window.attachEvent('onload', setVideoFrame);
}else{ //NO SUPPORT, lauching right now
setVideoFrame();
}
</script>
Notez que le script peut figurer n'importe où dans le code, mais en cas de non prise en charge des écouteurs d'événement (ce qui est très improbable avec les navigateurs actuels), la fonction est lancée immédiatement. Il doit donc être au moins après l'élément iframe
.
Regardez des exemples donnés d'utilisation d'un iframe avec l'attribut src et d'un attribut src dynamique avec les résultats GTMatrix.
<html>
<head>
<title>-</title>
</head>
<body>
<iframe id="myvideo" width="640" height="360" src="https://www.youtube.com/embed/PgcokT0AWHo" frameborder="0" allowfullscreen></iframe>
</body>
</html>
Voici le résultat de GTMatrix pour le code ci-dessus.
Maintenant, vérifiez le code src dynamique.
<html>
<head>
<title>-</title>
<script type="text/javascript">
function test()
{
document.getElementById('myvideo').src = 'https://www.youtube.com/embed/PgcokT0AWHo';
}
</script>
</head>
<body onload="test();">
<iframe id="myvideo" width="640" height="360" frameborder="0" allowfullscreen></iframe>
</body>
</html>
Examinons maintenant le résultat GTMatrix après l’application de src dynamique à l’iframe.
J'espère que ces exemples vous aideront à évaluer votre problème.
J'avais le même problème pour un site Web que je faisais et je suis tombé sur ce lien Comment "Lazy Load" incorporer des vidéos youtube
Lors du chargement de la page, il affiche une fausse section du lecteur youtube (composée de css et de la vignette de votre image vidéo) sur la page Web. Lorsque l'utilisateur clique dessus, il remplace cette fausse section par l’Iframe et c’est à ce moment que le lecteur sera chargé.
Code du site web
(function() {
// get's all video wrapper divs
var youtube = document.querySelectorAll(".youtube");
// iterates through all the divs
for (var i = 0; i < youtube.length; i++) {
/*
gets the video id we mentioned in the data-embed attribute
to generate image thumbnail urls, youtube has several
resolutions.
- mqdefault 320 x 180
- hqdefault 480 x 360
- sddefault - 640 x 480
- maxresdefault - 1920 x 1080
*/
var source = "https://img.youtube.com/vi/" + youtube[i].dataset.embed + "/sddefault.jpg";
/*
creates new image and sets the source attribute to the thumbnail
url we generated above and sets it to load the image on page load
*/
var image = new Image();
image.src = source;
image.addEventListener("load", function() {
youtube[i].appendChild(image);
}(i));
/*
below is where the magic happens, we attach click listeners to the
video embed divs and when clicked we create a new iframe and sets
it inside the video wrapper div and only then will the js files
associated with the embedded video be loaded
*/
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;
}
<!-- (1) video wrapper, data-embed contains ID of the Youtube video-->
<div class="youtube" data-embed="AqcjdkPMPJA">
<!-- (2) the "play" button -->
<div class="play-button"></div>
</div>
Vous pourriez remplacer:
<iframe src="https://www.youtube.com/embed/LcIytqkbdlo" height="180" width="320"></iframe>
avec
<div class="youtube" id="LcIytqkbdlo" style="width: 320px; height: 180px;"></div> <script src="https://labnol.googlecode.com/files/youtube.js"></script>
comme illustré ici: https://www.mainstreethost.com/blog/light-youtube-embeds-faster-page-load/
Vous pouvez trouver un autre article utile qui traite votre problème ici: https://mikeindustries.com/blog/archive/2007/06/widget-deployment-with-wedje
WEDJE crée un différé multi-plateformes et multi-navigateurs en utilisant le modèle d'objet document (DOM) pour ajouter un div, créer un élément de script, puis ajouter l'élément de script au div, tous avec JavaScript. Voici un exemple de technique:
<script type="text/javascript"> // create div below
(function( ){document.write('<div id="wedje_div_example">Loading widget...<\/div>');
s=document.createElement('script'); // create script element
s.type="text/javascript"; // assign script to script element
s.src="http://www.example.com/scripts/widget.js";
// assign script s to div element
setTimeout("document.getElementById('wedje_div_example').appendChild(s)",1);})( )
</script>
Lorsque ces éléments sont liés entre eux de cette manière, les navigateurs semblent découpler le chargement et l'exécution du code JavaScript attaché, rendant ainsi l'exécution du widget asynchrone! Voici le fichier JavaScript externe correspondant, widget.js, qui récupère le div créé précédemment et charge une image:
document.getElementById('wedje_div_example').innerHTML+='<img src="https://www.example.com/images/example.gif" width="60" height="60" />';
Une approche possible consiste à ne pas utiliser la variable iframe
directement, mais à l'ajouter à un écouteur d'événement, tel que click.
Jetez un coup d'œil à cette solution que j'utilise depuis longtemps sur mon site web (promotion sans vergogne - Démo )
Ici, je montre une image d'aperçu avec un bouton de lecture. Lorsque l'utilisateur clique sur l'image, l'iframe YouTube est ajouté dynamiquement à la page, ce qui économise des tonnes d'octets lors du chargement de la page. Le code ci-dessous est presque prêt pour la production et peut être utilisé selon vos besoins.
if (document.querySelector("#videoPlayer")) {
document.querySelector("#videoPlayer a").addEventListener("click", playVideo);
}
function playVideo() {
var player = document.getElementById("videoPlayer");
var id = player.getAttribute("data-id");
player.classList.add("loaded");
var src =
"https://www.youtube.com/embed/" +
id +
"?autoplay=1&autohide=1&rel=0&modestbranding=1&showinfo=0&border=0&wmode=opaque&theme=light&iv_load_policy=3";
var iframe =
"<iframe width='100%' height='100%' src='" +
src +
"' scrolling='no frameborder='0' allowfullscreen></iframe>";
player.innerHTML = iframe;
return false;
}
#videoPlayer {
background-color: #000;
max-width: 100%;
overflow: hidden;
position: relative;
cursor: pointer;
height: 380px;
width: 100%;
margin: 1em auto;
}
#videoPlayer:after {
content: attr(data-title);
position: absolute;
bottom: 0;
left: 0;
display: block;
background: rgba(0, 0, 0, 0.5);
width: 100%;
max-height: 100px;
text-align: left;
padding: 1em;
font-size: 1.2em;
color: #fff;
transition: opacity 0.7s ease-in-out;
}
#videoPlayer:hover:after {
opacity: 0;
}
#videoPlayer .thumb {
bottom: 0;
display: block;
left: 0;
margin: auto;
max-width: 100%;
position: absolute;
right: 0;
top: 0;
width: 100%;
height: auto;
opacity: 0.8;
filter: alpha(opacity=80);
transition: all 200ms ease-out;
-webkit-transition: all 200ms ease-out;
}
#videoPlayer .thumb:hover {
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
#videoPlayer .play {
filter: alpha(opacity=90);
opacity: 0.9;
height: 97px;
left: 50%;
margin-left: -38px;
margin-top: -38px;
position: absolute;
top: 50%;
width: 136px;
background: url("http://i.imgur.com/TxzC70f.png");
background-repeat: no-repeat;
}
#videoPlayer.loaded:after {
display: none;
}
<div id="videoPlayer" data-title="NBA 2K18 - Get Shook Trailer" data-id="lwBqitrE3ww"> <a title="Click to play video : NBA 2K18 - Get Shook Trailer"> <img class="thumb" alt="NBA 2K18 - Get Shook Trailer" src="https://1.bp.blogspot.com/-X4naiytBpyU/WZRt5d3P1iI/AAAAAAAADq8/y4IAHBmh39kqdwu8THECuObG3r9HIfa9wCLcBGAs/s800/nba-2k18-get-shook-trailer-hoopsvilla.jpg" /><span class="play"></span></a></div>
</div>
Remarque: La démo ci-dessus risque de ne pas fonctionner en raison de problèmes de cookies croisés. S'il vous plaît voir la démo sur codepen .
Améliorations possibles:
<iframe width="640" height="360" src="" data-src="https://www.youtube.com/embed/PgcokT0AWHo" frameborder="0" allowfullscreen></iframe>
<script>
function init() {
var vidDefer = document.getElementsByTagName('iframe');
for (var i=0; i<vidDefer.length; i++) {
if(vidDefer[i].getAttribute('data-src')) {
vidDefer[i].setAttribute('src',vidDefer[i].getAttribute('data-src'));
}
}
}
window.onload = init;
</script>