Я не знал, что произойдет, когда JavaScript будет загружен - PullRequest
0 голосов
/ 19 июля 2011

Я создал пример ниже, где страница динамически загружает temp.js внизу HTML-страницы.В temp.js есть небольшая функция сна, которая привязывает браузер на 3 секунды, прежде чем регистрировать «Script Loaded».В самом низу HTML-страницы записывается «Страница загружена»

Теперь, зная, что я знаю о браузерах, загрузке ресурсов и однопоточной природе JS, я думал, что это произойдет.

  1. Отображается HTML
  2. console.log 'Page Loaded'
  3. Около трех секунд ожидания, пока temp.js все набирает
  4. console.log говорит мне 'Script Loaded '

, но на самом деле происходит следующее:

  1. console.log' Page Loaded '(почти мгновенно)
  2. Пустая страница около трехсекунд
  3. Отображается HTML и console.log сообщает мне 'Script Loaded'

Вы ожидаете такого поведения?


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 ]

4 голосов
/ 19 июля 2011

Что происходит

  • Разбор HTML-кода
  • <script> блок 1 анализируется и добавляет новый тег сценария к <head>
  • <script> блок 2 анализируется и загружается страница журнала
  • <script> блок в голове анализируется, и он запускает функцию блокировки блокировки
  • проход 3 секунды
  • Сценарий загружен в журнал
  • <head> завершил разбор и отображает <body>
  • Страница отображается.

Изменение

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

К

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

И HTML-страница будет загружаться первой.

Проблема в в том, что все скрипты в <head> должны быть загружены и запущены до отображения тела HTML

2 голосов
/ 19 июля 2011

Я не знаю, какова поддержка или поведение async в разных браузерах, но я подозреваю, что основная проблема связана с вашей функцией sleep.

Обычно функция сна будет делать именно то, что говорит - приостановить текущий исполняемый поток и снова разбудить его через x секунд. Ваша функция сна выполняет все, кроме - она ​​выполняет условный цикл while (now + ms) > ((new Date()).getTime ()) столько раз, сколько способен браузер. Это, безусловно, заблокирует любое другое выполнение Javascript и, в зависимости от браузера, предположительно повлияет и на рендеринг страницы.

Вы хотите использовать setTimeout для эмуляции сна в Javascript:

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