Введение
Если вы интересуетесь тем, как работают браузеры, то наверняка читали статьи о том, как в Chrome реализован рендеринг и композитинг с аппаратным ускорением. Во-первых, Ускоренный рендеринг в Chrome: модель слоев – отличное введение в то, как Chrome использует концепцию слоев для отрисовки своей страницы; и для более глубокого погружения Композитинг с ускорением графического процессора в Chrome обсуждает, как Chrome использует эти слои вместе с графическим процессором для рендеринга вашей страницы.
Философский вопрос
Потратив много времени на написание программных растеризаторов для 3D-целей, я понял, что некоторые свойства CSS должны иметь разную производительность при отрисовке вашей страницы. Например, растеризация небольшого изображения на экране – это совершенно другой алгоритм, нежели рисование тени на произвольной фигуре. Поэтому возник вопрос: как различные свойства CSS влияют на вес рендеринга страницы?
Моя цель состояла в том, чтобы классифицировать большой набор свойств/значений CSS по времени их отрисовки, чтобы мы могли понять, какие типы свойств CSS более эффективны, чем другие. Чтобы сделать это, я написал несколько автоматизированных скриптов, которые позволили мне получить числовые значения времени отрисовки CSS. Вот как это работало:
- Создайте набор отдельных HTML-страниц, каждая из которых содержит один элемент DOM и некоторые перестановки прикрепленных к нему свойств CSS.
- Запустите скрипт автоматизации, который для каждой страницы будет выполнять следующие действия:
- Запустите браузер Chrome.
- Загрузка страницы
- Создать изображение Skia для страницы.
- Проверьте каждое изображение Skia Picture с помощью Skia Benchmark, чтобы получить данные о времени.
- Выгрузите все временные метки и посмотрите на цифры. (Это важная часть…)
При такой настройке мы генерируем набор HTML-страниц, каждая из которых содержит уникальную перестановку свойств и значений CSS. Например, вот два HTML-файла:
<style>
#example1 {
background: url(foo.png) top left / 50% 60%;
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
И ещё один, более сложный
<style>
#example1 {
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(circle closest-corner, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1">WOAH</div>
Ниже приведен вариант последнего примера, в котором изменено только значение радиального градиента:
<style>
#example1
{
background-color:#eee;
box-shadow: 1px 2px 3px 4px black;
border-radius: 50%;
background: radial-gradient(farthest-side, white, black);
padding: 20px;
margin-top: 10px;
margin-right: 20px;
text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>
Затем каждая страница загружается в новом экземпляре Chrome (чтобы убедиться, что на время загрузки не повлияли какие-либо устаревшие состояния при перезагрузке страницы), и создается Skia Picture (*.SKP), чтобы оценить, какие команды Skia используются для отрисовки страницы. После того как для каждого HTML-файла будут созданы SKP-файлы, мы запускаем ещё один пакетный процесс, чтобы передать файлы *.SKP в приложение Skia Benchmark (созданное на основе исходного кода Skia), которое выводит среднее время, затраченное на отрисовку этой страницы.
Оценка данных
Теперь у нас есть возможность примерно оценить, сколько времени занимает отрисовка набора свойств CSS. Или, скорее, мы можем начать ранжировать свойства CSS по их производительности отрисовки. Ниже приведен график, созданный в бета-версии Chrome 27, на котором показаны все временные данные, полученные в ходе этого процесса. Обратите внимание, что все данные могут меняться, поскольку Chrome постоянно совершенствуется.
Каждая вертикальная полоса представляет время отрисовки страницы с одной комбинацией свойств CSS (увеличено в 100 раз; истинное значение масштаба этого графика составляет 0,1,56 мс). Красивые линии, но в таком виде они бесполезны. Чтобы найти полезные тенденции, нужно провести анализ данных.
Во-первых, мы находим доказательства того, что некоторые свойства CSS просто дороже отображать, чем другие. Например, отрисовка тени на элементе DOM включает в себя многопроходную операцию со сплайнами и другими сложными вещами, в отличие от непрозрачности, которую должно быть легче визуализировать.
Во-вторых, и это более интересно, комбинации свойств CSS могут иметь большее время отрисовки, чем сумма их частей. На первый взгляд это кажется странным: мы ожидаем, что A + B = C, а не 2, 2C. Например, если добавить box-shadow и border-radius-stroke :
Интересно, что это не просто свойство box-shadow, а определенная перестановка значений. Например, ниже показана группировка box-shadow : 50% и border-radius с вариациями значений.
Судя по данным, это продолжается некоторое время. Существует множество различных странных комбинаций, и мой набор тестов едва ли затрагивает их все; есть ещё множество тестов и комбинаций, которые могут дать интересные результаты.
Как определить вес отрисовки страницы
Отслеживая время отрисовки каждого элемента на странице, разработчики могут оценить, как это влияет на скорость отклика сайта. Вот несколько советов, которые помогут вам начать:
- Используйте режим непрерывной отрисовки в Инструментах разработчика Chrome, чтобы понять, какие свойства CSS замедляют работу.
- Включите проверку CSS в существующий процесс проверки кода, чтобы выявлять проблемы с производительностью. Ищите в CSS места, где вы используете элементы, которые, как известно, требуют больше ресурсов, например градиенты и тени. Спросите себя, действительно ли они нужны.
- Если вы сомневаетесь, всегда выбирайте вариант, который обеспечит лучшую производительность. Пользователи могут не помнить, какова ширина полей в столбцах, но они запомнят, насколько удобно было пользоваться вашим сайтом.
Заключительное мнение
Самое интересное в этом эксперименте – то, что время будет меняться с каждой версией Chrome (надеемся, что в сторону уменьшения). Программное обеспечение браузера постоянно меняется. То, что сегодня работает медленно, завтра может работать быстро. Вы можете убрать из этой статьи box-shadow: 1px 2px 3px 4px, чтобы не добавлять его к элементу, у которого уже есть border-radius:5. Однако более ценный вывод заключается в том, что свойства CSS напрямую влияют на время отрисовки страницы.