【问题标题】:Creating many YouTube iframe players slows down initial page load创建许多 YouTube iframe 播放器会减慢初始页面加载速度
【发布时间】:2013-01-29 22:36:34
【问题描述】:

我正在使用 youtube api 添加很多视频,比本示例中的更多,一页 15 个,另一页 30 个;逻辑是一样的

// load  api
  var tag = document.createElement('script');
  tag.src = "//www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  // make player array
  var players = new Array();

  function onYouTubeIframeAPIReady() {
    players[0] = new YT.Player('player1', { //player1 is a div id in the html, this is how it works throughout the page
      height: '405',
      width: '720',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }
    });
    players[1] = new YT.Player('player2', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      suggestedQuality: 'large',
      iv_load_policy: '3',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }
    });
    players[2] = new YT.Player('player3', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      suggestedQuality: 'large',
      iv_load_policy: '3',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }     
    });
     players[3] = new YT.Player('player4', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      iv_load_policy: '3',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }
    });
      players[4] = new YT.Player('player5', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });
    players[5] = new YT.Player('player6', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });
    players[6] = new YT.Player('player7', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });




  }
//to stop the video from playing
  $(document).click( function() {
    //loop players array to stop them all
    $(players).each(function(i){
       this.pauseVideo();
      });
  });

上述代码的问题在于 iframe 需要很长时间才能加载到页面上。这会干扰其他 javascript,例如触发包含某些视频的模式窗口。

在下一个示例中,我将视频分成 3 个数组,其中 2 个在诸如模态按钮事件之类的事件上触发。

// load  api
  var tag = document.createElement('script');
  tag.src = "//www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  // make player array
  var players = new Array();
  var players2 = new Array();
  var players3 = new Array();

  function onYouTubeIframeAPIReady() {
    players[0] = new YT.Player('player1', {
      height: '405',
      width: '720',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }
    });




   $('.btn-1').click( function(){

      players2[0] = new YT.Player('player3', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      suggestedQuality: 'large',
      iv_load_policy: '3',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }     
    });
     players2[1] = new YT.Player('player4', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      iv_load_policy: '3',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3
          }
    });
      players2[2] = new YT.Player('player5', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });



  });


   $('.btn-2').click( function(){


  players3[0] = new YT.Player('player7', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });
    players3[1] = new YT.Player('player8', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });
     players3[2] = new YT.Player('player9', {
      height: '315',
      width: '560',
      videoId: 'Sqd3jUPq3Lw',
      playerVars: { 
          'rel': 0, 
          'enablejsapi': 1,
          'iv_load_policy': 3 
          }
    });
   });
   }

  $(document).click( function() {
    //loop players array to stop them all

    $(players).each(function(i){
       this.pauseVideo();
      });   
      $(players2).each(function(i){
       this.pauseVideo();
      });
      $(players3).each(function(i){
       this.pauseVideo();
      });
        });

这实际上会错开加载时间。页面加载很快,虽然模态框需要更长的时间,但我觉得用户愿意再等待几秒钟来加载 iframe。

最后一个功能不起作用的是在文档点击时暂停所有视频(当用户点击离开模式时很有用)。具有讽刺意味的是,如果我摆脱了按钮单击事件,函数 onYouTubeIframeAPIReady 能够为所有三个数组创建 iframe。一旦将这些点击事件添加到函数中,pausevideo 函数就会失败。

我已通读 youtube 文档,但没有找到解决方案。

提前感谢您的帮助。

【问题讨论】:

    标签: jquery youtube-api youtube-javascript-api


    【解决方案1】:

    要回答您的具体问题,即当您采用将 YT.Player 对象存储在单独数组中的方法时,为什么所有视频都没有暂停,我假设这是因为您只是在迭代 @987654324 @array 并在每个玩家上调用pauseVideo(),而不是对players2(和players3)数组执行相同的操作。

    要解决一次加载大量播放器时 JavaScript 执行延迟的更大问题,您需要记住页面上的 JavaScript 执行是单线程的,如果您在 onYouTubeIframeAPIReady() 上花费时间,那么这必然会阻止任何处理程序或其他代码同时执行。因此,如果这对您来说是个问题,您应该尽量减少在该函数中占用执行线程的时间。这样做的一种技术是将一些执行为deferred via setTimeout() calls 的操作排队。

    这可能看起来像(未经测试):

    var players = [];
    
    function onYouTubeIframeAPIReady() {
      window.setTimeout(function() {
        players.push(new YT.Player('player1', {
          // Your player1 config here...
        }));
      }, 0);
    
      // Many other window.setTimeout() calls...
    
      window.setTimeout(function() {
        players.push(new YT.Player('player50', {
          // Your player50 config here...
        }));
      }, 0);
    }
    

    您可能还会看到将controls: 2 添加到您的playerVars 中的一些好处,例如documented here

    顺便说一句,您将iv_load_policy 指定为传递给YT.Player 构造函数的选项中的值。那什么也做不了;你应该把它作为一个值放在playerVars 部分(你已经在做)。

    【讨论】:

    • 杰夫,感谢您为此所做的工作。我使用的解决方案是在 iframe 的 url 中构建播放器变量,然后我使用 jquery 将 src 更改为 data-src 以启用和禁用特定点击事件的 iframe。虽然,可能不是 youtube 建议的方法,但它工作得很好,而且比我开始使用的一堆 javascript 少得多。再次感谢您,这确实很有帮助,并且肯定提高了我对事件处理程序的理解。
    猜你喜欢
    • 2014-07-18
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    相关资源
    最近更新 更多