Эффективность отрисовки

Пользователи замечают, если сайты и приложения работают плохо, поэтому оптимизация производительности рендеринга имеет решающее значение!

Современные пользователи ожидают, что страницы будут интерактивными и будут работать без задержек. Именно на этом вам нужно сосредоточить свое время и усилия. Страницы должны не только быстро загружаться, но и оперативно реагировать на действия пользователя в течение всего жизненного цикла. Именно этот аспект пользовательского опыта измеряется показателем Interaction to Next Paint (INP). Хорошее значение INP означает, что страница стабильно и надежно реагирует на действия пользователя.

Хотя важным компонентом того, что делает страницу быстрой, является количество JavaScript, которое вы выполняете в ответ на взаимодействие с пользователем, пользователи ожидают визуальных изменений в пользовательском интерфейсе. Визуальные изменения в пользовательском интерфейсе являются результатом нескольких типов работ, часто называемых рендерингом, и эта работа должна выполняться как можно быстрее, чтобы пользовательский интерфейс работал быстро и надежно.

Чтобы страницы быстро реагировали на действия пользователей, нужно понимать, как браузер обрабатывает HTML, JavaScript и CSS, и следить за тем, чтобы ваш код и код сторонних разработчиков выполнялся как можно эффективнее.

Примечание о частоте обновления экрана

Пользователь взаимодействует с сайтом на мобильном телефоне.
Частота обновления экрана – важный фактор, который нужно учитывать при создании сайтов, быстро реагирующих на действия пользователя.

Большинство современных устройств обновляют экран 60 раз в секунду. Каждое обновление создает визуальный вывод, который вы видите, и обычно называется кадром. В следующем видео показано, как работают фреймы:

Кадры на панели производительности в инструментах разработчика Chrome. При наведении курсора на ленту в верхней части экрана в подсказке появляется увеличенное изображение каждого кадра, на котором показано, как меню навигации на мобильном устройстве переходит в открытое состояние.

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

Учитывая, что типичный дисплей обновляется 60 раз в секунду, простые математические расчеты показывают, что у браузера есть 16,66 миллисекунды на создание каждого кадра. Однако на практике браузеру требуется время на обработку каждого кадра, поэтому все операции должны выполняться в течение 10 миллисекунд. Если вы не уложитесь в этот бюджет, частота кадров упадет, а содержимое страницы на экране будет дрожать. Это явление часто называют помехами.

Однако ваши цели меняются в зависимости от типа работы, которую вы пытаетесь выполнить. Соблюдение порога в 10 миллисекунд имеет решающее значение для анимации, где объекты на экране интерполируются по серии кадров между двумя точками. Когда речь идет о дискретных изменениях в пользовательском интерфейсе, то есть о переходе из одного состояния в другое без какого-либо движения между ними, рекомендуется, чтобы такие изменения происходили в течение периода времени, который кажется пользователю мгновенным. В таких случаях часто упоминается цифра 100 мс, но пороговое значение INP, соответствующее хорошему уровню, составляет 200 мс или меньше, чтобы учесть более широкий спектр устройств с различными возможностями.

Каковы бы ни были ваши цели – будь то создание множества кадров, необходимых для анимации, чтобы избежать рывков, или просто максимально быстрое создание дискретного визуального изменения в пользовательском интерфейсе – понимание того, как работает конвейер пикселей браузера, имеет важное значение для вашей работы.

Конвейер пикселей

Есть пять основных областей, о которых вам нужно знать и помнить в своей работе веб-разработчика. Эти пять областей – те, которые вы можете контролировать больше всего, и каждая из них представляет собой ключевую точку в конвейере от пикселей до экрана:

Полный конвейер пикселей, состоящий из пяти шагов: JavaScript, стиль, макет, отрисовка и композиция.
Иллюстрация полного конвейера пикселей.
  • JavaScript. Обычно используется для обработки задач, которые приводят к визуальным изменениям в пользовательском интерфейсе. Например, это может быть функция animate в jQuery, сортировка набора данных или добавление элементов DOM на страницу. Однако для визуальных изменений JavaScript не обязателен: анимации CSS, переходы CSS и Web Animations API позволяют анимировать контент страницы.
  • Расчет стилей. Процесс определения того, какие правила CSS применяются к каким элементам HTML на основе соответствующих селекторов. Например, .headline – это селектор CSS, который применяется к любому элементу HTML со значением атрибута class, содержащим класс headline. После того как правила определены, они применяются и вычисляются окончательные стили для каждого элемента.
  • Макет. Как только браузер узнает, какие правила применяются к элементу, он может начать вычислять геометрию страницы, например, сколько места занимают элементы и где они появляются на экране. Модель макета веб-страницы означает, что один элемент может влиять на другие. Например, ширина элемента <body> обычно влияет на размеры его дочерних элементов по всему дереву, поэтому процесс может быть довольно сложным для браузера.
  • Отрисовка. Отрисовка – это процесс заполнения пикселей. Она включает в себя отрисовку текста, цветов, изображений, границ, теней и, по сути, каждого визуального аспекта элементов после того, как был рассчитан их макет на странице. Рисование обычно выполняется на нескольких поверхностях, часто называемых слоями.
  • Компоновка. Поскольку части страницы могли быть отрисованы на нескольких слоях, их необходимо применить к экрану в правильном порядке, чтобы страница отображалась должным образом. Это особенно важно для элементов, которые перекрывают друг друга, поскольку ошибка может привести к тому, что один элемент будет неправильно отображаться поверх другого.

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

Возможно, вы слышали термин "растеризация", используемый в сочетании с "рисованием". Это потому, что покраска на самом деле состоит из двух задач:

  1. Создание списка вызовов отрисовки.
  2. Заполняю пиксели.

Последний процесс называется растеризацией, поэтому всякий раз, когда вы видите записи отрисовки в DevTools, вы должны думать о том, что они включают растеризацию. В некоторых архитектурах создание списка вызовов отрисовки и растеризация выполняются в разных потоках, но разработчик не может этим управлять.

Не обязательно, чтобы каждый кадр проходил через все этапы конвейера. На самом деле есть три способа, которыми конвейер обычно воспроизводится для данного кадра, когда вы вносите визуальные изменения, либо с помощью JavaScript, CSS, либо с помощью Web Animations API.

1. JS/CSS > Стиль > Макет > Отрисовка > Компоновка

Полный конвейер пикселей, без пропущенных шагов.

Если вы измените свойство макета, например то, которое меняет геометрию элемента, например ширину, высоту или его положение (например, свойства CSS left или top), браузеру необходимо проверить все остальные элементы и "перекомпоновать" страницу. Все затронутые области нужно будет перекрасить, а затем объединить все элементы.

2. JS/CSS > Стиль > Отрисовка > Компоновка

Конвейер пикселей с пропущенным шагом макета.

Если вы изменили свойство элемента в CSS, которое влияет только на отрисовку, например background-image, color или box-shadow, то для визуального обновления страницы не требуется этап макета. Пропуская шаг макета, где это возможно, вы избегаете потенциально дорогостоящей работы по макету, которая в противном случае могла бы внести значительную задержку в создание следующего кадра.

3. JS/CSS > Стиль > Композитный

Конвейер пикселей с пропущенными шагами макета и рисования.

Если вы измените свойство, которое не требует ни макета, ни отрисовки, браузер может сразу перейти к этапу компоновки. Это самый дешевый и наиболее желательный путь через конвейер пикселей для точек высокого давления в жизненном цикле страницы, таких как анимация или прокрутка. Интересный факт: Chromium оптимизирует прокрутку страницы так, чтобы она по возможности выполнялась только в потоке компоновщика. Это означает, что даже если страница не отвечает, вы все равно можете прокручивать ее и видеть части, которые ранее были отрисованы на экране.

Производительность веб-страниц – это искусство избегать работы, максимально повышая эффективность любой необходимой работы. Во многих случаях речь идет о работе с браузером, а не против него. Стоит иметь в виду, что работа, ранее показанная в конвейере, различается с точки зрения вычислительных затрат; некоторые задачи по своей сути более затратны, чем другие!

Давайте рассмотрим разные части конвейера. Мы рассмотрим распространенные проблемы, а также способы их диагностики и устранения.

Оптимизация отрисовки в браузере

Скриншот курса Udacity

Производительность важна для пользователей, и чтобы создать хороший пользовательский опыт, веб-разработчикам необходимо создавать веб-сайты, которые быстро реагируют на взаимодействие с пользователем и плавно отображаются. Эксперт по производительности Пол Льюис поможет вам избавиться от задержек и создать веб-приложения, которые поддерживают производительность 60 кадров в секунду. Вы научитесь профилировать приложения и выявлять причины неоптимальной производительности рендеринга. Вы также изучите конвейер рендеринга браузера и обнаружите шаблоны, которые упрощают создание быстрых веб-сайтов, которые пользователям будет приятно использовать.

Это бесплатный курс, предлагаемый через Udacity, и вы можете пройти его в любое время.