Содержание

На заметку: Это статья содержит числовые значения, зависящие от определённой сборки браузера. Со временем эти числа изменятся, как и представленные здесь данные.

Введение

Если вы из тех людей, кто интересуется тем, как работают браузеры, тогда вы уже наверняка прочли нескольких отличных статей, раскрывающих подробности рендеринга и сборки страниц Chrome с использованием графического ускорителя (GPU). Например, «Ускоренный рендеринг в Chrome: Многоуровневая модель» это отличное введением в то, как Chrome использует понятие слоя для отрисовки страниц. Для более глубокого понимания процесса вы можете прочесть статью «Ускорение сборки страницы в Chrome с использованием GPU», которая рассматривает то, как Chrome использует свои слои вместе с GPU для отрисовки страницы.

Краткий пересказ этих статей состоит в том, что с помощью аппаратного ускорения Chrome отрисует вашу страницу, растеризируя элементы страницы в прямоугольные области. Затем эти кусочки передаются графическому ускорителю, где аппаратная часть завершит их отрисовку на экране. Этот процесс называется сборкой (Compositing). Chrome будет перемещать области в память и из памяти, основываясь на необходимости и эвристиках исполнения, которые могут меняться в зависимости от платформы.

Философский вопрос

Я долго занимался написанием программных растеризаторов для работы с 3D, и для меня стало очевидным то, что производительность при отрисовке страницы будет меняться в зависимости от использованных CSS-свойств. Например, растеризация маленького изображения на экран происходит по совершенно другому алгоритму, чем отрисовка тени падающей на объект произвольной формы. Таким образом возникает вопрос: как различные CSS-свойства влияют на время отрисовки страницы?

Моей целью было классифицировать большой набор CSS-свойств и значений по времени их отрисовки, чтобы мы понимали, какие CSS-свойства лучше с точки зрения производительными. Чтобы этого добиться, я с помощью кувалды и такой-то матери соорудил систему для оценки времени отрисовки CSS. Система работает следующим образом:

Программный пакет растеризации Chrome называется SKIA, и он управляет не только растеризацией веб-страницы, но также и используется для удовлетворения всех нужд HTML5 Canvas API (блоки, линии, растровые заливки, тени, размытия, все вызовы Chrome для превращения DOM в пиксели). Чтобы облегчить отладку процесса отрисовки, SKIA позволяет сохранить в файлах Skia Picture (*.SKP) записи о всех командах, использованных при отрисовке страницы.

Используя этот пакет, мы генерируем набор HTML-страниц, в котором каждая страница содержит уникальную комбинацию CSS-свойств и их значений, например:

<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">ВАУ</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">ВАУ</div>

Каждая страница затем загружается в новом экземпляре Chrome (чтобы быть уверенными в том, что временные замеры не были как-либо искажены устаревшими состояниями при перезагрузке страницы), затем создается Skia Picture (*.SKP) для определения списка Skia-команд, использованных для её отрисовки. Как только для каждой страницы сгенерируются SKP-файлы, мы запускаем другую серию операций и пропускаем файлы *.SKP через приложение Skia Benchmark (собранное из исходников Skia), которое выводит среднее время, требующееся для отрисовки конкретной страницы.

Оценка полученных данных

С этого момента у нас есть возможность составить грубую картину того, сколько времени требуется для отрисовки тех или иных наборов CSS-свойств. Мы даже можем начать упорядочивать CSS-свойства по производительности их отрисовки. Ниже приведен большой график, сделанный с помощью Chrome 27 beta и отображающий весь набор временных замеров из нашего процесса. Обратите внимание, что все эти данные могут меняться по мере того, как Chrome будет становиться быстрее и быстрее.

График

Каждая вертикальная черта представляет собой время отрисовки страницы с единственной комбинацией CSS-свойств (увеличено в 100 раз, истинный масштаб составляет всего [0, 1.56ms]). Здесь множество симпатичных линий, но в таком формате они в общем-то бесполезны. Нам нужно проанализировать данные, чтобы обнаружить в них закономерности.

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

График

Далее, интересно то, что, CSS-свойства могут иметь большее время отрисовки в комбинации, нежели в сумме по отдельности. С точки зрения наблюдателя это немного странно, мы обычно ожидаем, что A+B = C, а не 2,2C. В качестве примера — добавление box-shadow и border-radius-stroke:

График

Что действительно интересно, так это то, что здесь уже не просто свойство box-shadow само по себе, а особое значение permutation. Например, ниже показывается комбинация box-shadow: 50% и border-radius с некоторыми разновидностями значений.

График

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

Вычисление времени отрисовки страницы

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

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

Заключение

Наиболее интересно в этом эксперименте то, что временные замеры будут продолжать изменяться с каждой новой версией Chrome (и, надеюсь, отрисовка свойств ускорится). «Браузерное» ПО — это все время изменяющаяся область. То, что медленно работает сегодня, может ускориться уже завтра. Из этой статьи вы, конечно, можете вынести то, что нужно избегать указания box-shadow: 1px 2px 3px 4px для элемента, у которого уже есть border-radius: 5. Хотя если вы сделаете вывод, что CSS-свойства напрямую влияют на время отрисовки вашей страницы, это принесет вам значительно больше пользы.

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

Материалы для дальнейшего чтения