Большие размеры DOM-модели оказывают большее влияние на интерактивность, чем вы думаете. В этом руководстве объясняется, почему и что можно сделать.
Другого пути нет: при создании веб-страницы у неё будет объектная модель документа (DOM) . DOM представляет собой структуру HTML-кода страницы и предоставляет JavaScript и CSS доступ к её структуре и содержимому.
Проблема, однако, заключается в том, что размер DOM влияет на способность браузера быстро и эффективно отображать страницу. Как правило, чем больше DOM, тем дороже первоначальный рендеринг страницы и её последующее обновление в течение жизненного цикла страницы.
Это становится проблемой на страницах с очень большими DOM-объектами, когда взаимодействия, изменяющие или обновляющие DOM, приводят к дорогостоящей работе по верстке, которая влияет на скорость отклика страницы. Дорогостоящая работа по верстке может повлиять на время взаимодействия страницы до следующей отрисовки (INP) . Если вы хотите, чтобы страница быстро реагировала на действия пользователя, важно убедиться, что размеры DOM не превышают необходимых значений.
Когда DOM страницы слишком большой?
По данным Lighthouse , размер DOM страницы считается чрезмерным, если он превышает 1400 узлов. Lighthouse начинает выдавать предупреждения, когда количество узлов в DOM страницы превышает 800. Рассмотрим следующий HTML-код:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
В приведённом выше коде четыре элемента DOM: элемент <ul>
и три его дочерних элемента <li>
. На вашей веб-странице почти наверняка будет гораздо больше узлов, поэтому важно понимать, как контролировать размеры DOM, а также использовать другие стратегии оптимизации рендеринга после того, как вы уменьшите размер DOM страницы до максимально возможного.
Как большие DOM влияют на производительность страниц?
Большие DOM влияют на производительность страницы несколькими способами:
- Во время первоначального отображения страницы. При применении CSS к странице создаётся структура, похожая на DOM, известная как объектная модель CSS (CSSOM) . По мере повышения специфичности селекторов CSS, CSSOM становится сложнее, и требуется больше времени для выполнения необходимых действий по верстке, стилизации, компоновке и отрисовке, необходимых для отображения веб-страницы на экране. Эта дополнительная работа увеличивает задержку взаимодействия, происходящего на ранних этапах загрузки страницы.
- Когда взаимодействия изменяют DOM, будь то посредством вставки или удаления элементов, либо посредством изменения содержимого и стилей DOM, работа, необходимая для отображения этого обновления, может привести к весьма затратным затратам на верстку, стилизацию, компоновку и отрисовку. Как и в случае с первоначальным отображением страницы, повышение специфичности селекторов CSS может увеличить нагрузку на отображение при вставке HTML-элементов в DOM в результате взаимодействия.
- Когда JavaScript обращается к DOM, ссылки на DOM-элементы сохраняются в памяти. Например, если вы вызываете
document.querySelectorAll
для выбора всех элементов<div>
на странице, расход памяти может быть значительным, если результат возвращает большое количество DOM-элементов.

Все это может повлиять на интерактивность, но второй пункт в списке выше особенно важен. Если взаимодействие приводит к изменению DOM, это может привести к значительному объему работы, что может привести к снижению качества INP на странице.
Как измерить размер DOM?
Размер DOM можно измерить двумя способами. Первый метод использует Lighthouse. При запуске аудита статистика по DOM текущей страницы будет отображаться в разделе «Не допускайте превышения размера DOM» в разделе «Диагностика». В этом разделе можно увидеть общее количество DOM-элементов, DOM-элемент с наибольшим количеством дочерних элементов, а также DOM-элемент с самой высокой глубиной вложения.
Более простой метод — использование консоли JavaScript в инструментах разработчика любого популярного браузера. Чтобы получить общее количество HTML-элементов в DOM, можно использовать следующий код в консоли после загрузки страницы:
document.querySelectorAll('*').length;
Если вы хотите отслеживать изменение размера DOM в режиме реального времени, вы также можете воспользоваться инструментом мониторинга производительности . С помощью этого инструмента вы можете сопоставлять операции по компоновке и стилизации (и другие аспекты производительности) с текущим размером DOM.

Если размер DOM приближается к пороговому значению предупреждения Lighthouse DOM или вообще не достигает его, следующим шагом будет выяснение того, как уменьшить размер DOM, чтобы улучшить способность вашей страницы реагировать на действия пользователя и тем самым повысить INP вашего веб-сайта.
Как измерить количество элементов DOM, затронутых взаимодействием?
Если вы профилируете медленное взаимодействие в лабораторных условиях и подозреваете, что оно может быть связано с размером DOM страницы, вы можете выяснить, сколько элементов DOM было затронуто, выбрав любой фрагмент активности в профилировщике с надписью «Пересчитать стиль» и изучив контекстные данные на нижней панели.

На снимке экрана выше обратите внимание, что перерасчёт стиля работы (если он выбран) показывает количество затронутых элементов. Хотя на снимке экрана выше показан крайний случай влияния размера DOM на отрисовку работы на странице с большим количеством DOM-элементов, эта диагностическая информация в любом случае полезна для определения того, является ли размер DOM ограничивающим фактором времени, необходимого для отрисовки следующего кадра в ответ на взаимодействие.
Как уменьшить размер DOM?
Помимо проверки HTML-кода вашего сайта на наличие ненужной разметки, основной способ уменьшить размер DOM — это уменьшить его глубину. Одним из признаков того, что ваш DOM может быть излишне глубоким, является разметка, которая выглядит примерно так на вкладке «Элементы» в инструментах разработчика браузера:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Когда вы видите подобные закономерности, вы, вероятно, можете упростить их, сделав структуру DOM более плоской. Это сократит количество DOM-элементов и, вероятно, даст возможность упростить стили страниц.
Глубина DOM также может быть признаком используемых вами фреймворков. В частности, компонентные фреймворки, например, те, которые используют JSX , требуют вложения нескольких компонентов в родительский контейнер.
Однако многие фреймворки позволяют избегать вложенности компонентов, используя так называемые фрагменты. Компонентные фреймворки, предлагающие фрагменты как функциональную возможность, включают (но не ограничиваются) следующие:
Используя фрагменты в выбранном вами фреймворке, вы можете уменьшить глубину DOM. Если вас беспокоит влияние уплощения DOM-структуры на стили, вам может быть полезно использовать более современные (и быстрые) режимы макета, такие как Flexbox или Grid .
Другие стратегии, которые следует рассмотреть
Даже если вы приложите все усилия, чтобы сделать дерево DOM плоским и удалить ненужные HTML-элементы, чтобы сохранить его максимально компактным, оно всё равно может быть довольно большим и требовать значительного объёма рендеринга, поскольку изменяется в ответ на действия пользователя. Если вы оказались в такой ситуации, есть другие стратегии, которые можно использовать для ограничения объёма рендеринга.
Рассмотрите аддитивный подход
Возможно, вы столкнулись с ситуацией, когда большая часть вашей страницы изначально не видна пользователю при первом отображении. Это может быть хорошей возможностью реализовать отложенную загрузку HTML, исключив соответствующие части DOM при запуске, но добавив их, когда пользователь взаимодействует с теми частями страницы, для которых изначально скрыты эти элементы.
Этот подход полезен как во время начальной загрузки, так и, возможно, даже после неё. При начальной загрузке страницы вы берёте на себя меньше работы по рендерингу, а значит, начальная HTML-нагрузка будет легче и будет отображаться быстрее. Это даст взаимодействиям в этот критический период больше возможностей для выполнения, меньше конкурируя за внимание основного потока.
Если многие части страницы изначально скрыты при загрузке, это также может ускорить другие взаимодействия, запускающие повторную отрисовку. Однако по мере того, как другие взаимодействия увеличивают объём DOM, нагрузка на отрисовку будет увеличиваться по мере роста DOM на протяжении жизненного цикла страницы.
Постепенное добавление данных в DOM может быть сложным и имеет свои недостатки. Если вы идёте по этому пути, вам, вероятно, придётся отправлять сетевые запросы для получения данных, необходимых для заполнения HTML-кода, который вы собираетесь добавить на страницу в ответ на взаимодействие с пользователем. Хотя сетевые запросы в реальном времени не учитываются в показателе загрузки (INP), они могут увеличить воспринимаемую задержку. По возможности, добавьте индикатор загрузки или другой индикатор загрузки данных, чтобы пользователи понимали, что что-то происходит.
Ограничить сложность селектора CSS
Когда браузер анализирует селекторы в вашем CSS, ему приходится просматривать дерево DOM, чтобы понять, как эти селекторы применяются к текущему макету и применяются ли они вообще. Чем сложнее селекторы, тем больше работы приходится выполнять браузеру для первоначальной отрисовки страницы, а также для увеличения количества перерасчётов стилей и работы с макетом, если страница изменяется в результате взаимодействия.
Используйте свойство content-visibility
CSS предлагает свойство content-visibility
, которое фактически позволяет лениво отрисовывать элементы DOM, находящиеся за пределами экрана. По мере приближения элементов к области просмотра они отображаются по требованию. Преимущества свойства content-visibility
заключаются не только в значительном сокращении объёма работы по отрисовке при первоначальном отображении страницы, но и в отказе от отрисовки элементов, находящихся за пределами экрана, при изменении DOM страницы в результате взаимодействия с пользователем.
Заключение
Уменьшение размера DOM до размера, необходимого только для достижения абсолютно необходимого, — хороший способ оптимизировать INP вашего сайта. Это позволит сократить время, необходимое браузеру для компоновки и рендеринга при обновлении DOM. Даже если существенно уменьшить размер DOM не удаётся, существуют методы, позволяющие изолировать рендеринг в поддереве DOM, например, CSS-контейнмент и CSS-свойство content-visibility
.
Как бы вы ни подошли к этому, создание среды, в которой работа по рендерингу минимизирована, а также сокращение объёма рендеринга страницы в ответ на взаимодействие, приведёт к тому, что ваш сайт будет восприниматься пользователями более отзывчиво. Это означает, что ваш INP для вашего сайта снизится, что, в свою очередь, положительно скажется на удобстве использования.