web-dev-qa-db-fra.com

Comment empêcher les appels YouTube js de ralentir le chargement des pages

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>
10
Genadinik

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.

5
Kaddath

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.

 enter image description here

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.

 enter image description here

J'espère que ces exemples vous aideront à évaluer votre problème.

2
Manish Nayak

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>

2
Ajmal Hassan

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" />';
1

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: 

  1. Soutenir plusieurs vidéos sur la même page. Il n'autorise actuellement qu'une seule vidéo. Cela peut être fait facilement avec les sélecteurs basés sur les classes.
0
<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> 
0
Nanhe Kumar