Когда мы входим в юридическуюurl
, сначала браузерDNS
Разрешение доменного имени, после получения IP-адреса сервера браузер отправляет серверуGET
Запросите, подождите, пока сервер вернется в нормальное состояние, а браузер начнет загрузку и парсинг.html
. Здесь только кратко описан процесс парсинга html браузером.
html
Страница в основном состоит изdom
,css
,javascript
и другие части, в том числеcss
а такжеjavascript
обе内联
так же может быть脚本
Представлено в виде курсаhtml
может также представитьimg
,iframe
и другие ресурсы. На самом деле все эти ресурсыdom
Форма тега встроена вhtml
странице, поэтому эта статья обобщаетhtml
Процесс синтаксического анализаdom
процесс разбора.
1 dom
процесс разбора
весьdom
Процесс синтаксического анализа顺序
,а также渐进式
из.
顺序
Это относится к началу с первой строки и анализу строки за строкой;渐进式
Это означает, что браузеру не терпится отобразить завершенную часть парсинга.Если мы проведем следующий эксперимент, мы обнаружим, что в断点
первыйdiv
Он уже отображается в браузере:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
first div
</div>
<script>
debugger
</script>
<div>
second div
</div>
</body>
</html>
теперь, когдаdom
Разбирается по порядку с первой строки, так что как судитьdom
Когда разбор закончен? Этот вопрос следует часто задавать на собеседованиях, например:
window.onload
а такжеDOMContentLoaded
Какая разница?
Я просто хотел посмотреть, понял ли яdom树
Когда сборка завершена, вопрос действительно важен, особенно несколько лет назад.jquery
стек технологий, потому что мы используемjavascript
действоватьdom
или датьdom
Связывание событий имеет предварительное условие, которое должно бытьdom树
был создан. весьhtml
страницыdom
Когда разбор завершен,dom树
Сборка завершена. После того, как дом построенdocument
Объект отправляет событияDOMContentLoaded
ставить в известностьdom树
Сборка завершена.
html
Начните парсинг с первой строки и столкнетесь外联
ресурс(外联css
,外联javascript
,image
,iframe
и т. д.) запросит соответствующий ресурс, затем процесс заблокируется, если будет запрошенdom
процесс разбора? Ответ зависит от ситуации, какие-то ресурсы будут, а какие-то нет. Следующее разделено на две категории в зависимости от того, будет ли он блокировать синтаксический анализ страницы:阻塞型
а также非阻塞型
, обратите внимание, что флаги, которые различают два типа ресурсов,document
отправка объектаDOMContentLoaded
Момент времени события, считающегося отправленнымDOMContentLoaded
только событиеdom树
Сборка завершена.
1.1 Блокировка
заблокируетdom
Проанализированные ресурсы в основном включают:
- встроенный css
- встроенный JavaScript
- Контур простого javascript
- Аутрич отложить javascript
- Контур css перед тегом javascript
Охватjavascript
Можно использоватьasync
а такжеdefer
Поэтому он делится на три категории:外联普通javascript
,外联defer javascript
,外联async javascript
, эти виды охватаjavascript
Подробности приведены далее в этой статье.dom
встретились при разборе外联普通javascript
Парсинг будет приостановлен и запрос будет полученjavascript
и выполнить, затем продолжить синтаксический анализdom树
.
для外联defer javascript
Здесь мы сосредоточимся на том, почему это также приписывается阻塞型
. Как упоминалось ранее, здесьdocument
отправка объектаDOMContentLoaded
событие для идентификацииdom树
сборка завершена, иdefer javascript
Он запрашивается и выполняется до отправки события, поэтому он также классифицируется как блокирующий, но вам нужно знать,defer
изjavascript
по фактуdom树
Сборка и отправкаDOMContentLoaded
Он запрашивается и выполняется между событиями, но если понимать это по-другому,<script>
сам тожеdom
отчасти нетрудно понять, почемуdefer
изjavascript
Будет вDOMContentLoaded
Выполняется перед отправкой.
Также обратите внимание, чтоjavascript标签之前的外联css
. На самом деле сказаноcss
Ресурс не должен блокироватьdom树
процесса сборки, в конце концовcss
влияет толькоdom
стиль, не влияетdom
структура,MDN
На это так поясняется:
The
DOMContentLoaded
event is fired when the initial HTML document has been completely loaded and parsed, without waiting forstylesheets
, images, and subframes to finish loading.
Но реальность таковаdom树
Сборка подлежитjavascript
блокировка, покаjavascript
При выполнении вы можете использовать что-то вродеWindow.getComputedStyle()
API, такие какdom
стили, такие как:
const para = document.querySelector('p');
const compStyles = window.getComputedStyle(para);
Поэтому браузеры обычно сталкиваются с<script>
этикетка перед этикеткой外联css
Запрошено и выполнено. Но обратите внимание, что здесь добавлено предварительное условиеjavascript标签之前的外联css
, что означает, чтоjavascript
зависит от исполнения外联css
. Этот легко упускаемый моментэта статьяТакже есть инструкции, рекомендуемые к прочтению.
Эти阻塞型
После того, как запрос ресурса выполнен и выполненdom树
Разбор завершен, тогдаdocument
объект будет отправленDOMContentLoaded
событие, сказалdom树
Сборка завершена.
1.2 Неблокирующий
не блокируетdom
Проанализированные ресурсы в основном включают:
- Контур css после тега javascript
- image
- iframe
- Схема асинхронного javascript
dom树
Будет отправлен после завершения синтаксического анализаDOMContentLoaded
событие, для外联css
Ресурсы делятся на две категории, одна находится в<script>
Перед меткой класс располагается по адресу<script>
после этикетки. роды<script>
после этикетки外联css
не блокируетdom树
аналитический.外联css
правильноdom树
Влияние процесса синтаксического анализа описано в очень хорошей статье здесь:DOMContentLoaded and stylesheets, рекомендуется к прочтению.
DOMContentLoaded
событие для идентификацииdom树
После того, как сборка завершена, как судить о других非阻塞型
Загрузка ресурса завершена? ответwindow.onload
. Поскольку событие отправляется слишком поздно, в нормальных условиях оно нам не нужно, но болееDOMContentLoaded
действовать как можно скорееdom
.
а такжеimage
,iframe
так же как外联async javascript
не будет блокироватьdom
Строительство дерева. здесь外联async javascript
Что это такое? В следующем разделе будет представлена общая外联javascript
.
2 外联javascript
процесс загрузки
html
можно импортировать на страницу内联javascript
, также можно ввести外联javascript
,外联javascript
Разделен на:
- Контур простого javascript
<script src="indx.js"></script>
- Аутрич отложить javascript
<script defer src="indx.js"></script>
- Схема асинхронного javascript
<script async src="indx.js"></script>
Первый из них外联普通javascript
, будет блокироватьhtml
анализ,html
Каждый раз, когда вы сталкиваетесь с таким<script>
Тег будет запрошен и выполнен, как показано на рисунке ниже, зеленый означаетhtml
Разбор; серым цветомhtml
Синтаксический анализ приостановлен; синий указывает外联javascript
Загрузка; розовый указываетjavascript执行
.
外联普通javascript
Процесс выполнения загрузки выглядит следующим образом:второй外联defer javascript
немного отличается,html
встретились при разборе<script>
Метка не блокирует парсинг, а будет временно храниться в очереди, ожидая полногоhtml
После завершения синтаксического анализа запрос и выполнение в порядке очередиjavascript
, но это外联defer javascript
Он будет отправлен после того, как все загружено и выполненоDOMContentLoaded
мероприятие,外联defer javascript
Процесс выполнения загрузки выглядит следующим образом:третий外联async javascript
не блокируетhtml
Процесс парсинга, обратите внимание на упомянутый здесь скрипт下载
Процесс не блокируетсяhtml
Разбираем, если загрузка завершенаhtml
Если парсинг не завершен, он будет приостановленhtml
Разбор, первое выполнение после завершения загрузкиjavascript
код для продолжения синтаксического анализаhtml
, процесс выглядит следующим образом:но еслиhtml
был проанализирован,外联async javascript
Если загрузка не была завершена, она не будет заблокированаDOMContentLoaded
рассылка событий. следовательно外联async javascript
Очень вероятно, что будет слишком поздно контролироватьDOMContentLoaded
события, такие какstackoverflow
ВверхЭта проблема.
Обратите внимание, что эти цифры взяты изздесь.
3 DOMContentLoaded
Проблемы совместимости
DOMContentLoaded
первоначальноfirefox
Предлагается, чтобы другие браузеры сочли его очень полезным и начали поддерживать его один за другим, но функции немного отличаются, напримерopera
серединаjavascript
Казнь не ждет外联css
нагрузка. доHTML5
выйдетDOMContentLoaded
стандартизированный, согласноHTML5
стандарт,javascript
Перед выполнением скрипт появляется в текущем<script>
предыдущий<link rel="stylesheet">
Должен быть полностью загружен.
Итак, как решить эту проблему до того, как все браузеры будут стандартизированыDOMContentLoaded
А проблемы с совместимостью? может относиться кjQuery
середина.ready()
Для реализации метода в интернете уже много разборов исходников этого метода, я не буду здесь разбирать, а сразу объясню принцип. На самом деле он используетсяMDN: DOMContentLoadedМетод совместимости, описанный в ,ie9
только что начал поддерживатьDOMContentedLoaded
,ie8
среда может быть обнаруженаdocument.readystate
статус для подтвержденияdom树
Завершена ли сборка.document.readystate
Включает 3 состояния:
- loading - загружается html-документ
- интерактивный — HTML-документ загружен и проанализирован, но ресурсы, такие как изображения, не загружены, что эквивалентно
DOMContentLoaded
- Complete - загружены все ресурсы, что эквивалентно
window onload
Поэтому мы судимdocument.readystate
статусinteractive
имитироватьDOMContentLoaded
момент времени. Но здесь следует отметить, что.ready()
Возьмем метод в качестве примера, мы можем вызвать его в следующих местах:
- встроенный JavaScript
- Контур простого javascript
- Аутрич отложить javascript
- Схема асинхронного javascript
3 из них непосредственно судят в трех местахdocument.readystate
Определенно естьloading
статус, только外联async javascript
может появитьсяdocument.readystate
дляinteractive
илиcompleted
состояние, потому что外联async javascript
не блокируетdom
парсится, так что для полного покрытия предыдущих 4 случаев нужно мониторитьdocument.readystate
Изменение:
if (document.readystate === 'interactive'
|| document.readystate === 'complete') {
// 调用ready回调函数
} else {
document.onreadystatechange = function () {
if (document.readystate === 'interative') {
// 调用ready回调函数
}
}
}
4 Цитаты
В основном обратитесь к следующим статьям, рекомендуемым к прочтению: