Вас когда-нибудь смущало, почему иногда ваши теги ‹script› не работают с JavaScript — JS, как вы ожидаете, или когда страница загружается, ваш CSS появляется с опозданием? ? (называется Flash of Unstyled Content или FOUC) Этих и многих других проблем можно избежать, если лучше понять, как на самом деле работает DOM — объектная модель документа.

Во-первых, базовое понимание того, как работают деревья, полезно для понимания того, как создается дерево DOM, и я не говорю о биологическом типе.

Деревья в информатике

Деревья представляют собой сложную структуру данных. Сложная структура данных — это еще один способ сказать, что это что-то, что обеспечивает организацию нескольких различных форм данных. Деревья данных подчиняются нескольким правилам:

  1. Каждое дерево начинается с самого верхнего узла, называемого корнем.
  2. Каждый узел может иметь неограниченное количество дочерних узлов, но только один родительский.
  3. Узел без дочерних элементов называется конечным узлом или конечным узлом.

Вы можете думать о древовидной структуре данных как о серии реальных деревьев, перевернутых вверх дном.

О деревьях есть еще много чего, но пока этого достаточно, чтобы знать. Так почему я заставляю вас читать о деревьях, спросите вы? Ну, деревья есть везде, в реальном мире и в виртуальном мире. Большинство компьютерных файловых структур на самом деле представляют собой древовидные структуры, еще одна большая, и та, с которой мы сегодня углубимся… да, вы уже догадались, это DOM.

Что такое ДОМ?

Что ж, DOM сам по себе не является деревом, но он состоит из деревьев, если быть точным, из двух — дерева DOM и дерева CSSOM. Они сложены вместе, чтобы веб-страницы, которые вы посещаете, выглядели так же красиво, как настоящее дерево.

Так что же такое ДОМ? DOM — это, по сути, API, который браузер предоставляет вам (вот почему некоторые страницы выглядят по-разному в других браузерах, поскольку они имеют тенденцию реализовывать DOM немного иначе, чем другие — кашель — IE). Этот API DOM позволит вам подключиться через JS к вашему дереву DOM или дереву рендеринга — в зависимости от того, на каком этапе вы находитесь на этапе построения страницы.

Подожди, подожди, подожди, что?

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

Большая часть этой магии — это то, что делает DOM, когда вы получаете ответ от серверов, он содержит исходный код для этой веб-страницы, мы предполагаем, что используемый язык разметки — HTML. Парсер HTML начинает создавать дерево DOM, в основном каждый элемент/тег преобразуется в узел, эти узлы содержат определенные для браузера правила о том, как он должен выглядеть и действовать. Затем любые элементы/теги внутри этого тега станут его дочерними элементами и так далее. Это не сопоставление исходного кода один к одному, синтаксический анализатор попытается исправить любой недопустимый HTML, и, конечно же, JS может его изменить. Этот синтаксический анализатор в конечном итоге построит дерево DOM со скоростью, зависящей от того, насколько оптимизирован код.

Таким образом, пока этот синтаксический анализатор строит дерево DOM, может происходить несколько других вещей, в зависимости от того, как разработчик закодировал веб-сайт. Вы когда-нибудь задумывались, почему лучше всего размещать теги ‹style› вверху, а теги ‹script› внизу документа? Это связано с тем, что в прошлом, если в тег ‹script› не добавлялись дополнительные параметры, он загружался синхронно и блокировал анализатор HTML, это могло происходить как во время загрузки файла, так и во время выполнения кода JS, это может привести к непредвиденным результатам, поскольку это будет взаимодействие с незавершенным деревом DOM. В настоящее время эта проблема в основном устранена, поскольку браузеры предварительно загружают скрипты с помощью причудливой механики загрузки, называемой спекулятивным синтаксическим анализом (который в основном представляет собой предварительную загрузку и загрузку в параллельных соединениях с небольшим количеством сахара). Спекулятивный синтаксический анализ будет предварительно загружать важные файлы, такие как внешний CSS, сценарии и изображения, в тег img, так что единственное, что блокирует синтаксические анализаторы, — это выполнение сценариев, а не получение ресурсов.

Как влияет CSSOM и Render Tree?

Теперь, когда мы немного разобрались, мы можем поговорить о том, как CSSOM и Render Tree влияют на все это. Оба очень важны для окончательной визуализации веб-страницы. Поскольку синтаксический анализатор HTML строит дерево DOM, новый синтаксический анализатор, называемый синтаксическим анализатором CSS, будет… как вы уже догадались, он создаст CSSOM — объектную модель CSS, которая является другим деревом, поэтому, чтобы избежать путаницы, я назову ее Дерево CSSOM.

На данный момент дерево DOM — это всего лишь скелет. Он содержит узлы элементов, их дочерние элементы и некоторые специфичные для браузера правила о том, как все должно выглядеть, например, некоторое раздражающее заполнение тега ‹p›; глядя на тебя Хром. Вот тут-то и появляется дерево CSSOM… как только оно и дерево DOM будут построены, они будут объединены для создания дерева всех деревьев, дерева рендеринга. Дерево рендеринга — это то, что браузер берет и использует для рендеринга конечной страницы пользователю. Помните, что в любой момент выполнения этих шагов, в зависимости от того, как написан код, JS может изменить любое из этих деревьев; это всегда может привести к непреднамеренным побочным эффектам и проблемам.

Как вы можете смягчить эти проблемы?

Конечно, все еще могут быть проблемы, если теги ‹script› все еще находятся в заголовке документа, поскольку JS может произойти до того, как дерево рендеринга будет завершено, иногда это может быть необходимо, но, как всегда, подумайте о том, как это может повлиять на Пользовательский опыт. Однако есть несколько способов смягчить эту проблему, наиболее очевидным из которых является размещение тегов ‹script› в нижней части документа, чтобы они загружались последними и не мешали синтаксическому анализатору HTML.

Чего вы обычно хотите избежать:

<html>
  <head>
  <title>Example</title>
  <script />  <!-- will interfere with parser -->
  </head>
  <body>
  <body/>
<html/>

Другой распространенный способ — использование атрибутов defer и async. defer выполнит сценарий после завершения синтаксического анализа HTML и в порядке тегов ‹script›, независимо от того, где они расположены в документе. Атрибут async будет выполнять скрипты, как только они закончат загрузку. Теперь, если теги ‹script› находятся в заголовке документа, то сценарии могут быть выполнены до того, как парсер HTML завершит работу.

Несколько замечаний: поскольку defer появился раньше, чем async, старые браузеры не смогут распознать атрибут async, поэтому лучше поставить отсрочку в тандеме. Еще одно примечание: атрибут async будет загружаться с более низким приоритетом по сравнению с другими ресурсами.

Что лучше:

<html>
  <head>
  <title>Example</title>
  <script defer />  <!-- will run after parser -->
  </head>
  <body>
  <body/>
<html/>

Что лучше:

<html>
  <head>
  <title>Example</title>
  </head>
  <body>
  <body/>
  <script async defer />  <!-- will run after parser -->
<html/>

Но подождите, это еще не все! Вы можете спросить, есть ли низкий приоритет, а как насчет высокого? Хороший вопрос, Тимми! На самом деле есть еще один атрибут, который вы можете добавить к тегам ‹style›, ‹script› и даже ‹image›, ‹font›, ‹video› и т. д. Это атрибут rel="preload", который указывает браузеру загрузить их. как можно скорее!

<link rel="preload" href="very_important.js" as="script">

В итоге

Надеюсь, это помогло вам немного глубже понять, как устроена модель DOM и ее составляющие, чтобы при написании кода вашего следующего веб-сайта вы могли оптимизировать его для обеспечения лучшего взаимодействия с пользователем. Кстати, такие фреймворки, как React и Svelte, еще больше абстрагируют это от разработчика с помощью встроенных стилей и сценариев, но об этом в другой раз.

Использованная литература:







Что такое DOM?
Объектная модель документа, или «DOM
, представляет собой интерфейс к веб-страницам. По сути, это API к странице, позволяющий…bitsofco.de»