Процесс превращения HTML, CSS и JavaScript в целостную веб-страницу довольно сложен и включает в себя некоторую магию. Вот что делает браузер:
- Создает DOM и CSSOM.
- Объединяет их в дерево рендеринга (элементы с
display: none
не учитываются). - Вычисляет геометрию макета и его элементов.
- Пиксель за пикселем отрисовывает визуальное представление, которое мы видим на экране.
В этой статье сосредоточимся на последней части: отрисовке.
Все эти действия — существенная нагрузка для браузера, а ведь их нужно осуществить не только при первой загрузке страницы, но и при любом изменении DOM (или CSSOM). Эту проблему частично решают различные фреймворки (например, React), которые способны оптимизировать изменения для избежания ненужного пересчета и рендеринга.
Возможно, вы слышали такие термины, как состояние (state), отрисовка компонентов (component rendering) или неизменяемость (immutability). Все они вносят свой вклад в оптимизацию изменений DOM.
Например, состояние веб-приложения может измениться,что приведет к изменению части пользовательского интерфейса. Однако это не затрагивает большинство других компонентов. React помогает ограничить отрисовку минимально необходимым количеством элементов.
Однако браузер может перерисовывать страницу даже без каких-либо изменений в DOM и/или CSSOM.

Приведенная выше диаграмма создана с помощью панели производительности Chrome в DevTools и показывает, сколько миллисекунд заняло выполнение каждой задачи в браузере после перезагрузки страницы. Отрисовка занимает значительную часть общего времени. В этом конкретном примере время увеличивается за счет анимированных GIF-файлов и элемента canvas
. Они не вызывают никаких изменений в DOM или стилях, но запускают рендеринг страницы.
Другим хорошим примером отрисовки без внешнего вмешательства, является CSS-свойство animation, которое распространено в интернете шире, чем GIF или canvas
. Анимация обычно начинается в ответ на пользовательские действия, например при наведении, но можно создавать даже довольно сложные анимации, постоянно работающие без особых усилий, что очень здорово.
Важно понимать, что эти анимации могут легко выйти из-под контроля и постоянно запускать перерисовку, что потребует большой вычислительной мощности. Конечно, есть некоторые правила, которые можно использовать, чтобы избежать этого. Наиболее очевидным является использование для манипуляций по возможности только свойств, не запускающих рендеринг (transform
и opacity
).
Мерцание отрисовки
Вы, вероятно, знакомы с панелью разработчика в браузере Google Chrome, но могли не знать о комбинации Ctrl(Cmd) + Shift + P
, которая открывает поиск и командное меню внутри этой панели.

Здесь есть множество полезных и интересных опций, в том числе относящихся к рендерингу.

Измеритель FPS может быть очень полезен для отладки анимации.

Границы слоев (layer borders) используются для отображения границ слоев по мере их отображения браузером, что позволяет легко распознавать любое преобразование или изменение размера.
Мерцание отрисовки (Paint flashing) выделяет области перерисовки.
Проверьте свой проект с помощью этих инструментов. Например, перерисовка, вероятно, произойдет при изменении цвета ссылок при наведении курсора. Это небольшое изменение и оно не должно вас беспокоить.
Исследование
Давайте рассмотрим проблему подробнее. Возьмем дизайн, который включает в себя «шумный» задний фон (эффект старого телевизора).

У формата GIF много проблем, и производительность, безусловно, одна из них, поэтому мы не станем его использовать это для фона всей страницы. Здесь вы можете подробнее узнать, почему следует избегать GIF.
Можно использовать JavaScript или canvas для отображения и скрытия элементов со слегка смещенным фоном. Но это кажется слишком сложным решением для простого бэкграунда. Попробуем справиться силами CSS.
Установим одноцветный фон, возьмем небольшое «шумное» PNG-изображение и используем его со свойствами background-image
и background-repeat
. А эффект шума обеспечит бесконечная анимация свойства background-position
.
See the Pen by Georgy Marchuk (@gmrchk) on CodePen.
Видите ли вы здесь проблему? Кажется, что это довольно элегантное решение, но воспользуйтесь инструментом paint flashing. Слой размером с фон постоянно перерисовывается без всяких действий пользователя. (Мерцание не будет видно во встроенном с Codepen фрагменте).
На правой части видео видно мерцание при отрисовке фона.
Это не очень здорово для производительности сайта и батарей ноутбуков.

Всего этого можно избежать, заменив анимацию background-position
на transform
или изменение opacity
.
See the Pen by Georgy Marchuk (@gmrchk) on CodePen.
Анимация фона — в целом не очень хорошая идея.
Проблема
При разработке веб-проектов всегда помните о том, что у ваших пользователей может не быть такого же мощного компьютера и скоростного интернета, как у вас. То, что хорошо выглядит на вашем 27-дюймовом 4К мониторе может совершенно исказиться на ноутбуке с разрешением 1366х768.
Хотя эта статья начиналась с браузерной отрисовки, ее основная задача — напомнить о влиянии нашего кода на производительность в целом. Отрисовка страницы служит хорошим примером того, что разработчик легко может упустить проблему, которая возникнет у пользователя. Если вы не проверяете свои проекты на медленных компьютерах, используйте удобные инструменты панели разработчика, чтобы понять, как видят ваш сайт другие люди
0 комментариев