Frontender Magazine

Содержание

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

Введение

Если вы из тех людей, кто интересуется тем, как работают браузеры, тогда вы уже наверняка прочли нескольких отличных статей, раскрывающих подробности рендеринга и сборки страниц 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-свойства напрямую влияют на время отрисовки вашей страницы, это принесет вам значительно больше пользы.

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

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

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Colt McAnlis
Автор:
Colt McAnlis
Twitter:
@duhroach
GitHub:
mainroach
Google Plus:
+ColtMcAnlis
Сaйт:
http://mainroach.blogspot.com
Игорь Дерябин
Переводчик:
Игорь Дерябин
Сaйт:
http://rodweb.ru/
Twitter:
@ru_rodweb