Я сделал несколько веб-проектов, но я не слишком много думаю о последовательности загрузки и выполнения обычной веб-страницы. Но теперь мне нужно знать детали. Трудно найти ответы от Google или SO, поэтому я создал этот вопрос.

Пример страницы выглядит так:

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

. Вот мои вопросы:

  1. Как загружается эта страница?
  2. Какова последовательность загрузки?
  3. Когда выполняется код JS? (встроенный и внешний)
  4. CSS выполнен (применен)?
  5. Когда выполняется $ (document) .ready?
  6. Будет ли загружен файл abc.jpg? Или это просто скачать kkk.png?

У меня есть следующее понимание:

  1. Браузер сначала загружает HTML (DOM).
  2. Браузер начинает загружать внешние ресурсы сверху вниз, строка за строкой.
  3. Если выполнено <script>, загрузка будет заблокирована, дождитесь загрузки и выполнения файла JS, а затем продолжите.
  4. Другие ресурсы (CSS / изображения) загружаются параллельно и выполняются при необходимости (например, CSS).

Или это так:

Браузер анализирует HTML (DOM) и получает внешние ресурсы в виде массива или структуры, подобной стеку. После загрузки HTML браузер начинает загружать внешние ресурсы в структуре параллельно и выполнять до тех пор, пока не будут загружены все ресурсы. Затем DOM будет изменен в соответствии с поведением пользователя в зависимости от JS.

Может ли кто-нибудь дать подробное объяснение того, что происходит, когда вы получаете ответ HTML-страницы? Отличается ли это в разных браузерах? Любая ссылка на этот вопрос?

ОО стиль. Обязательно прокрутите вверх и оставьте отзыв на код Дэна. Это мило и быстро и работает как шарм для меня.

Мы только что выпустили

Я провел эксперимент в Firefox с Firebug. И это выглядит следующим образом: alt text

В соответствии с вашим примером,

<html>
 <head>
  <script src="jquery.js" type="text/javascript"></script>
  <script src="abc.js" type="text/javascript">
  </script>
  <link rel="stylesheets" type="text/css" href="abc.css"></link>
  <style>h2{font-wight:bold;}</style>
  <script>
  $(document).ready(function(){
     $("#img").attr("src", "kkk.png");
  });
 </script>
 </head>
 <body>
    <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
    <script src="kkk.js" type="text/javascript"></script>
 </body>
</html>

примерно такой поток выполнения выглядит примерно так:

  1. Документ HTML загружается
  2. При разборе документа HTML начинается
  3. HTML Синтаксический анализ достигает <script src="jquery.js" ...
  4. jquery.js, загружается и анализируется
  5. HTML Синтаксический анализ достигает <script src="abc.js" ...
  6. abc.js загружается, анализируется и запускается
  7. HTML Синтаксический анализ достигает <link href="abc.css" ...
  8. abc.css, загружается и анализируется
  9. HTML Синтаксический анализ достигает <style>...</style>
  10. Анализируются и определяются внутренние правила CSS
  11. HTML Синтаксический анализ достигает <script>...</script>
  12. Анализируется и выполняется внутренний Javascript
  13. HTML Синтаксический анализ достигает <img src="abc.jpg" ...
  14. abc.jpg загружен и отображает
  15. HTML Синтаксический анализ достигает <script src="kkk.js" ...
  16. kkk.js загружается, анализируется и запускается
  17. Анализ синтаксического анализа документа HTML заканчивается

Обратите внимание, что загрузка может быть асинхронной и неблокируемой из-за поведения браузера. Например, в Firefox есть этот параметр, который ограничивает количество одновременных запросов на домен.

Кроме того, в зависимости от того, был ли компонент уже кэширован или нет, этот компонент может не запрашиваться снова в запросе ближайшего будущего. Если компонент был кэширован, компонент будет загружен из кэша вместо фактического URL.

Когда синтаксический анализ завершен, а документ готов и загружен, запускаются события onload. Таким образом, когда запускается onload, запускается $("#img").attr("src","kkk.png");. Итак:

  1. Документ готов, onload запущен.
  2. Хиты выполнения Javascript $("#img").attr("src", "kkk.png");
  3. kkk.png загружаются и загружаются в событие #img

Переменная $(document).ready(), фактически это событие вызывается, когда все компоненты страницы загружены и готовы. Подробнее об этом читайте: http://docs.jquery.com/Tutorials:Introduction_$ (document) .ready ()

Редактировать — эта часть более подробно описывает параллельную или не часть:

По умолчанию, и, насколько я понимаю, браузер обычно запускает каждую страницу тремя способами: анализатор HTML, Javascript / DOM и CSS.

Анализатор HTML отвечает за синтаксический анализ и интерпретацию языка разметки и, следовательно, должен иметь возможность вызывать другие 2 компонента.

Например, когда синтаксический анализатор сталкивается с этой строкой:

<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>

Парсер выполнит 3 вызова, два в Javascript и один в CSS. Во-первых, парсер создаст этот элемент и зарегистрирует его в пространстве имен DOM вместе со всеми атрибутами, связанными с этим элементом. Во-вторых, будет вызван синтаксический анализатор, чтобы связать событие onclick с этим конкретным элементом. Наконец, он сделает еще один вызов в потоке CSS, чтобы применить стиль CSS к этому конкретному элементу.

Выполнение сверху вниз и однопоточное. Javascript может выглядеть многопоточным, но факт в том, что Javascript является однопоточным. Вот почему при загрузке внешнего файла JavaScript разбор основной HTML-страницы приостанавливается.

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

Элемент будет доступен в DOM только после его анализа. Таким образом, при работе с конкретным элементом скрипт всегда помещается после или внутри события onload окна.

Сценарий, подобный этому, вызовет ошибку (в jQuery):

<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>
<div id="mydiv">Hello World</div>

Поскольку при синтаксическом анализе сценария элемент #mydiv все еще не определен. Вместо этого это будет работать:

<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>

или

<script type="text/javascript">/* <![CDATA[ */
  $(window).ready(function(){
                    alert($("#mydiv").html());
                  });
/* ]]> */</script>
<div id="mydiv">Hello World</div>

1) HTML загружен.

2) HTML анализируется постепенно. При получении запроса на актив браузер пытается загрузить ресурс. Конфигурация по умолчанию для большинства HTTP-серверов и большинства браузеров заключается в параллельной обработке только двух запросов. IE можно перенастроить, чтобы загружать неограниченное количество ресурсов параллельно. Стив Соудерс смог загрузить более 100 запросов параллельно в IE. Исключением является то, что запросы скриптов блокируют параллельные запросы ресурсов в IE. Вот почему настоятельно рекомендуется поместить весь JavaScript во внешние файлы JavaScript и поместить запрос непосредственно перед закрывающим тегом body в HTML.

3) После анализа HTML DOM обрабатывается. CSS отображается параллельно с отображением DOM практически во всех пользовательских агентах. Поэтому настоятельно рекомендуется поместить весь код CSS во внешние файлы CSS, которые запрашиваются как можно выше в & Lt ; head & Gt ; & lt ; / head & gt ; раздел документа. В противном случае страница обрабатывается до появления позиции запроса CSS в DOM, а затем рендеринг начинается заново сверху.

4) Только после полной визуализации DOM и разрешения всех ресурсов на странице либо по истечении времени ожидания JavaScript выполняется из события onload. IE7, и я не уверен насчет IE8, не быстро истекает время активов, если HTTP-ответ не получен от запроса ресурса. Это означает, что актив, запрашиваемый JavaScript, встроенным в страницу, то есть JavaScript, записанный в теги HTML, который не содержится в функции, может на несколько часов препятствовать выполнению события onload. Эта проблема может быть вызвана, если такой встроенный код существует на странице и не выполняется из-за столкновения пространства имен, которое вызывает сбой кода.

Из вышеперечисленных шагов наиболее ресурсоемким является анализ DOM / CSS. Если вы хотите, чтобы ваша страница обрабатывалась быстрее, напишите эффективный CSS, исключив избыточные инструкции и объединив инструкции CSS в наименьшее количество ссылок на элементы. Сокращение количества узлов в вашем DOM-дереве также приведет к более быстрому рендерингу.

Имейте в виду, что каждый актив, который вы запрашиваете из своего HTML или даже из своих ресурсов CSS / JavaScript, запрашивается с отдельным заголовком HTTP. Это потребляет пропускную способность и требует обработки для каждого запроса. Если вы хотите, чтобы ваша страница загружалась как можно быстрее, уменьшите количество HTTP-запросов и уменьшите размер вашего HTML. Вы не оказываете никакой помощи пользователю, усредняя вес страницы в 180 Кб только из HTML. Многие разработчики соглашаются с ошибкой, заключающейся в том, что пользователь принимает решение о качестве контента на странице за 6 наносекунд, а затем удаляет DNS-запрос со своего сервера и записывает свой компьютер, если он недоволен, поэтому вместо этого они предоставляют самую красивую страницу на 250 тыс. HTML. Сделайте свой HTML-код коротким и приятным, чтобы пользователь мог быстрее загружать ваши страницы. Ничто не улучшает пользовательский опыт, как быстрая и отзывчивая веб-страница.

Откройте свою страницу в Firefox и получите аддон HTTPFox. Он скажет вам все, что вам нужно.

Обнаружено это в archivist.incuito:

http://archivist.incutio.com/viewlist/css-discuss/76444

Когда вы впервые запрашиваете страницу, ваш браузер отправляет запрос GET на сервер, который возвращает HTML в браузер. Затем браузер начинает анализ страницы (возможно, до того, как она будет возвращена).

Когда он находит ссылку на внешнюю сущность, такую ​​как файл CSS, файл изображения, файл сценария, файл Flash или что-либо еще, внешнее по отношению к странице (либо на том же сервере / домене, либо нет), он готовится сделать еще один запрос GET для этого ресурса.

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

Время, необходимое для возврата объекта, зависит от его размера, нагрузки, которую в данный момент испытывает сервер, и активности каждой отдельной машины между машиной, на которой запущен браузер, и сервером. Список этих машин в принципе может быть разным для каждого запроса, поскольку одно изображение может перемещаться из США ко мне в Великобританию через Атлантику, а другое с того же сервера выходит через Тихий океан, Азию и Европу, что занимает больше времени. Таким образом, вы можете получить последовательность, подобную следующей, где страница имеет (в этом порядке) ссылки на три файла сценария и пять файлов изображения, все различающихся размеров:

  1. GET script1 и script2 ; запрос очереди для script3 и images1-5.
  2. script2 прибывает (это меньше, чем script1): GET script3, очередь images1-5.
  3. script1 прибывает ; GET image1, очередь images2-5.
  4. image1 прибывает, ПОЛУЧИТЕ image2, очередь images3-5.
  5. Сценарий 3 не может быть получен из-за проблемы с сетью — GET script3 снова (автоматическая повторная попытка).
  6. image2 прибывает, script3 все еще не здесь ; GET image3, очередь images4-5.
  7. изображение 3 прибывает ; GET image4, очередь image5, script3 еще в пути.
  8. image4 прибывает, GET image5 ;
  9. image5 прибывает.
  10. script3 прибыл.

Короче говоря: любой старый порядок, в зависимости от того, что делает сервер, что делает остальная часть Интернета, и есть ли что-либо с ошибками и должно быть повторно выбрано. Это может показаться странным способом ведения дел, но было бы буквально невозможно для Интернета (не только для WWW) работать с какой-либо степенью надежности, если бы это не было сделано таким образом.

Кроме того, внутренняя очередь браузера может не извлекать объекты в том порядке, в котором они отображаются на странице — это не требуется ни по одному стандарту.

(О, и не забудьте о кешировании как в браузере, так и в кеширующих прокси, используемых провайдерами для облегчения загрузки сети.)

Если вы спрашиваете об этом, потому что хотите ускорить свой веб-сайт, посетите страницу Yahoo на Короче говоря, вы можете использовать переменные . У этого есть много лучших методов для ускорения Вашего веб-сайта.

Dynatrace AJAX Edition показывает точную последовательность загрузки, анализа и выполнения страницы.

AFAIK, браузер (по крайней мере, Firefox) запрашивает каждый ресурс, как только он его анализирует. Если он встречает тег img, он запросит это изображение, как только тег img будет проанализирован. И это может произойти даже до того, как он получит весь документ HTML … то есть он все еще может загружать документ HTML, когда это произойдет.

Для Firefox существуют очереди браузера, которые применяются в зависимости от того, как они установлены в about: config. Например, он не будет пытаться загрузить более 8 файлов одновременно с одного сервера … дополнительные запросы будут поставлены в очередь. Я думаю, что есть ограничения для каждого домена, для каждого прокси-сервера и другие вещи, которые описаны на веб-сайте Mozilla и могут быть установлены в about: config. Я где-то читал, что IE не имеет таких ограничений.

Событие jQuery ready запускается, как только основной HTML-документ был загружен и проанализирован DOM. Затем событие загрузки запускается после загрузки и анализа всех связанных ресурсов (CSS, изображений и т. Д.). Это ясно показано в документации по jQuery.

Если вы хотите контролировать порядок загрузки всего, я считаю, что самый надежный способ сделать это — использовать JavaScript.

Выбранный ответ, похоже, не относится к современным браузерам, по крайней мере, в Firefox 52. Я заметил, что запросы на загрузку ресурсов, таких как css, javascript, отправляются до того, как анализатор HTML достигает элемента, например

<html>
  <head>
    <!-- prints the date before parsing and blocks HTMP parsering -->
    <script>
      console.log("start: "   (new Date()).toISOString());
      for(var i=0; i<1000000000; i  ) {};
    </script>

    <script src="jquery.js" type="text/javascript"></script>
    <script src="abc.js" type="text/javascript"></script>
    <link rel="stylesheets" type="text/css" href="abc.css"></link>
    <style>h2{font-wight:bold;}</style>
    <script>
      $(document).ready(function(){
      $("#img").attr("src", "kkk.png");
     });
   </script>
 </head>
 <body>
   <img id="img" src="abc.jpg" style="width:400px;height:300px;"/>
   <script src="kkk.js" type="text/javascript"></script>
   </body>
</html>

Что Я обнаружил, что время начала запросов на загрузку ресурсов CSS и JavaScript не блокировалось. Похоже, что Firefox имеет сканирование HTML и определяет ключевые ресурсы (ресурс img не включен) перед началом анализа HTML.