JavaScript часто является триггером визуальных изменений. Иногда эти изменения вносятся непосредственно посредством манипуляций со стилем, а иногда посредством вычислений, которые приводят к визуальным изменениям, таким как поиск или сортировка данных. Несвоевременный или длительно выполняемый JavaScript может быть частой причиной проблем с производительностью, и вам следует постараться минимизировать его влияние, где это возможно.
Расчет стиля
Изменение DOM путем добавления и удаления элементов, изменения атрибутов, классов или воспроизведения анимации приводит к тому, что браузер пересчитывает стили элементов и, во многих случаях, макет части или всей страницы. Этот процесс называется расчетом стиля .
Браузер начинает расчет стилей с создания набора соответствующих селекторов, чтобы определить, какие классы, псевдоселекторы и идентификаторы применимы к тому или иному элементу. Затем он обрабатывает правила стиля из соответствующих селекторов и определяет, какие окончательные стили имеет элемент.
Роль пересчета стиля в задержке взаимодействия
Взаимодействие с следующей отрисовкой (INP) — это ориентированный на пользователя показатель производительности во время выполнения, который оценивает общую реакцию страницы на ввод пользователя. Он измеряет задержку взаимодействия с момента взаимодействия пользователя со страницей до момента, когда браузер рисует следующий кадр, отображающий соответствующие визуальные обновления пользовательского интерфейса.
Важным компонентом взаимодействия является время, необходимое для рисования следующего кадра. Работа по рендерингу, выполняемая для представления следующего кадра, состоит из многих частей, включая расчет стилей страницы, которые выполняются непосредственно перед работой над макетом, рисованием и композицией. В этом руководстве основное внимание уделяется затратам на расчет стилей, но сокращение любой части общей продолжительности рендеринга взаимодействия также снижает его общую задержку.
Уменьшите сложность ваших селекторов
Упрощение селекторов CSS может помочь ускорить расчеты стиля вашей страницы. Простейшие селекторы ссылаются на элемент CSS только по имени класса:
.title {
/* styles */
}
Но по мере роста любого проекта ему, вероятно, потребуется более сложный CSS, и в итоге вы можете получить селекторы, которые выглядят следующим образом:
.box:nth-last-child(-n+1) .title {
/* styles */
}
Чтобы определить, как эти стили применяются к странице, браузер должен эффективно спросить: «Является ли этот элемент с классом title
с родительским элементом класса box
, который является дочерним элементом минус-nth-плюс-1 его родительского элемента?» это может занять некоторое время для браузера. Чтобы упростить это, вы можете изменить селектор на более конкретное имя класса:
.final-box-title {
/* styles */
}
Эти замещающие имена классов могут показаться неуклюжими, но они значительно упрощают работу браузера. Например, в предыдущей версии, чтобы браузер знал, что элемент является последним в своем типе, он должен сначала знать все обо всех других элементах, чтобы определить, могут ли какие-либо элементы, следующие за ним, быть nth-last-child
. Это может быть намного более затратным в вычислительном отношении, чем сопоставление селектора с элементом только на основе имени его класса.
Уменьшите количество стилизованных элементов
Еще один фактор производительности (часто более важный, чем сложность селектора) — это объем работы, которую необходимо выполнить при изменении элемента.
В общих чертах, наихудшая стоимость расчета стиля вычисляемых элементов — это количество элементов, умноженное на количество селекторов, поскольку браузеру необходимо хотя бы один раз проверить каждый элемент на соответствие каждому стилю, чтобы увидеть, соответствует ли он.
Вычисления стиля могут быть нацелены непосредственно на несколько элементов, вместо того, чтобы делать недействительной всю страницу. В современных браузерах это, как правило, не является проблемой, поскольку браузеру не всегда нужно проверять все элементы, на которые может повлиять изменение. С другой стороны, старые браузеры не всегда оптимизированы для таких задач. Там, где это возможно, вам следует уменьшить количество недействительных элементов .
Оцените стоимость перерасчета вашего стиля
Есть несколько способов измерить стоимость пересчета стилей в браузере. Каждый из них зависит от того, хотите ли вы измерить его в браузере в вашей среде разработки или же вы хотите измерить, сколько времени занимает этот процесс у реальных пользователей на вашем веб-сайте.
Измерение стоимости пересчета стиля в Chrome DevTools
Один из способов измерить стоимость пересчета стилей — использовать панель производительности в Chrome DevTools. Для начала выполните следующие действия:
- Откройте Инструменты разработчика.
- Перейдите на вкладку «Производительность» .
- Установите флажок Статистика селектора (необязательно).
- Нажмите Запись .
- Взаимодействуйте со страницей.
Когда вы остановите запись, вы увидите что-то вроде следующего изображения:
Полоса вверху представляет собой миниатюрную диаграмму пламени, которая также отображает количество кадров в секунду. Чем ближе активность к нижней части полосы, тем быстрее браузер отрисовывает кадры. Если вы видите, что диаграмма пламени выравнивается вверху с красными полосами над ней, значит, у вас есть работа, которая приводит к длительному выполнению кадров.
Стоит присмотреться к длительным кадрам во время взаимодействия, например прокрутки. Если вы видите большой фиолетовый блок, увеличьте масштаб действия и выберите любую работу с надписью «Пересчитать стиль», чтобы получить дополнительную информацию о потенциально дорогостоящих работах по перерасчету стиля.
При нажатии на событие отображается его стек вызовов. Если работа рендеринга была вызвана взаимодействием с пользователем, он вызывает JavaScript, который инициировал изменение стиля. Он также показывает количество элементов, на которые влияет это изменение (в данном случае чуть более 900 элементов), и сколько времени занял расчет стиля. Вы можете использовать эту информацию, чтобы попытаться найти исправление в своем коде.
Если перед выполнением трассировки вы установили флажок «Статистика селектора» в настройках панели производительности , то на нижней панели трассировки появится дополнительная вкладка с таким же названием.
Эта панель предоставляет полезные данные об относительной стоимости каждого селектора, что позволяет вам идентифицировать дорогие селекторы CSS.
Дополнительную информацию см. в документации CSS Selector Stats .
Измерьте стоимость перерасчета стиля для реальных пользователей
Если вам интересно узнать, сколько времени требуется для пересчета стилей для реальных пользователей вашего веб-сайта, API Long Animation Frames предоставляет вам необходимые для этого инструменты. Данные из этого API были добавлены в библиотеку JavaScript web-vitals
, включая время пересчета стиля.
Если вы подозреваете, что задержка представления взаимодействия является основным фактором, влияющим на INP страницы, вам нужно выяснить, какая часть этого времени тратится на пересчет стилей на странице. Подробнее читайте о том , как измерить время пересчета стиля в полевых условиях .
Ресурсы
- Статистика селектора в Chrome DevTools
- Недействительность стиля в Blink
- Взаимодействие со следующей отрисовкой (INP)
- Библиотека JavaScript
web-vitals
- Измерьте время пересчета стиля в полевых условиях
Героическое изображение из Unsplash , автор Маркус Списке .