Как загрузить и выполнить последовательность веб-страницы?

Я сделал некоторые веб-проекты, но я не слишком много думаю о загрузке и последовательности выполнения обычной веб-страницы. Но теперь мне нужно знать подробности. Трудно найти ответы от 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>

Итак, вот мои вопросы:

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

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

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

Или это так:

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

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

Спасибо.

EDIT:

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

Ответ 1

Согласно вашему образцу,

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

примерно поток выполнения примерно следующий:

  • Документ HTML загружается
  • Разбор документа HTML начинается
  • HTML Parsing достигает <script src="jquery.js" ...
  • jquery.js загружается и анализируется
  • Разбор HTML достигает <script src="abc.js" ...
  • abc.js загружается, анализируется и запускается
  • Разбор HTML достигает <link href="abc.css" ...
  • abc.css загружается и анализируется
  • Разбор HTML достигает <style>...</style>
  • Внутренние правила CSS анализируются и определяются
  • Разбор HTML достигает <script>...</script>
  • Внутренний Javascript анализируется и запускается
  • HTML Parsing достигает <img src="abc.jpg" ...
  • abc.jpg загружается и отображается
  • HTML Parsing достигает <script src="kkk.js" ...
  • kkk.js загружается, анализируется и запускается
  • Разбор документа HTML заканчивается.

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

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

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

  • Документ готов, onload уволен.
  • Выполнение Javascript выполняется $("#img").attr("src", "kkk.png");
  • kkk.png загружается и загружается в #img

Событие $(document).ready() на самом деле является событием, когда все компоненты страницы загружены и готовы. Подробнее об этом: http://docs.jquery.com/Tutorials:Introducing_$(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 после его анализа. Таким образом, при работе с определенным элементом script всегда помещается после или внутри события onload окна.

Script, как это приведет к ошибке (в jQuery):

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

Поскольку при анализе script элемент #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>

Ответ 2

1) Загружается HTML.

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

  • GET script1 и script2; запрос очереди для сценариев3 и изображений1-5.
  • script2 приходит (он меньше, чем скрипт1): GET script3, queue images1-5.
  • script1 прибывает; GET image1, очереди изображений2-5.
  • image1, GET image2, очереди изображений3-5.
  • script3 не удается выполнить из-за проблемы с сетью - GET script3 снова (автоматический повтор).
  • image2 приходит, скрипт3 все еще не здесь; GET image3, очереди изображений4-5.
  • изображение 3 прибывает; GET image4, queue image5, скрипт3 все еще находится на пути.
  • image4, GET image5;
  • image5 прибывает.
  • script3 прибывает.

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

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

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

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