我不知道在'延迟加载'JavaScript时会发生这种情况

时间:2011-07-19 13:00:37

标签: javascript lazy-loading

我创建了下面的示例,其中页面在HTML页面的底部动态加载temp.js。 temp.js有一个小睡眠功能,在记录'Script Loaded'之前将浏览器绑定3秒钟。在HTML页面的最底部,它记录了一个“页面加载”

现在,了解我对浏览器的了解,下载资源以及JS的单线程特性我认为会发生这种情况。

  1. 显示HTML
  2. console.log'Page Loaded'
  3. 大约三秒钟的等待,而temp.js会这样做
  4. console.log告诉我'Script Loaded'
  5. 但实际上发生的是这个

    1. console.log'页面加载'(几乎立即)
    2. 空白页约三秒
    3. 显示HTML并且console.log告诉我'Script Loaded'
    4. 这是你期望的行为吗?


      function sleep (ms) {
        var now = (new Date()).getTime ();
        while ((now + ms) > ((new Date()).getTime ())) {
        }
      }
      sleep (3000);
      console.log ('Script Loaded');
      

      <html lang="en-US">
        <head>
          <meta charset="UTF-8">
          <title>querySelectorAll</title>
        </head>
        <body>
          <ul>
            <li><a href="">One</a></li>
            <li><a href="">Two</a></li>
          </ul>
      
          <div id="nick">
            <img src="image.png" alt="" width="10" height="10" />
            <img src="image.png" alt="" width="10" height="10" />
            <img src="image.png" alt="" width="10" height="10" />
          </div>
          <!-- <script type="text/javascript" src="temp.js"></script> -->
          <script type="text/javascript">
            (function() {
              var e = document.createElement('script');
              e.src = 'temp.js';
              e.async = true;
              document.getElementsByTagName("head")[0].appendChild(e);
            })();
          </script>
          <script type="text/javascript">
            console.log('Page Loaded');
          </script>
        </body>
      </html>
      

2 个答案:

答案 0 :(得分:4)

会发生什么

  • 解析了一些HTML
  • 解析了
  • <script>块1,并将新脚本标记添加到<head>
  • 解析
  • <script>块2并加载日志页面
  • 解析了
  • <script> head in head并运行阻塞睡眠功能
  • 3秒钟通过
  • 已加载脚本
  • <head>块已完成解析并呈现<body>
  • 显示页面。

更改

document.getElementsByTagName("head")[0].appendChild(e);

document.getElementsByTagName("body")[0].appendChild(e);

HTML页面将首先加载。

问题是 <head>中的所有脚本都必须在呈现HTML正文之前加载并运行

答案 1 :(得分:2)

我不知道async在浏览器中的支持或行为是什么,但我怀疑主要问题在于您的sleep功能。

通常,睡眠功能将完全按照其说法执行操作 - 暂停当前正在执行的线程并在x秒内再次唤醒它。你的睡眠功能正在做任何事情 - 它正在执行while循环条件(now + ms) > ((new Date()).getTime ())和浏览器一样多次。这肯定会锁定任何其他Javascript执行,并且取决于浏览器可能会影响页面呈现。

您想使用setTimeout在Javascript中模拟睡眠:

setTimeout(function() {
console.log ('Script Loaded');
}, 3000);