Не делайте анимации через изменение DOM атрибутов
Заметка о том, почему лучше не делать анимации через изменение DOM атрибутов (padding, margin) или через изменение CSS-свойств left, top при значении position заданным как absolute
Предположим у вас есть вот такая анимация (взято из статьи, How to create high-performance CSS animations)
Есть два способа как можно реализовать анимацию. Первый способ через изменение свойств top
и left
.box {
position: absolute;
top: 10px;
left: 10px;
animation: move 3s ease infinite;
}
@keyframes move {
50% {
top: calc(90vh - 160px);
left: calc(90vw - 200px);
}
}
Второй через изменение свойства transform: translate
.box {
position: absolute;
top: 10px;
left: 10px;
animation: move 3s ease infinite;
}
@keyframes move {
50% {
transform: translate(calc(90vw - 200px), calc(90vh - 160px));
}
}
Многие опытные разработчики скажут вам, что делайте анимацию через изменение свойства transform: translate
. Но почему способ через transform
работает лучше? Давайте разберемся!
Ответ на этот вопрос вращается вокруг сокращения paint операций, благодарю выносу в отдельный слой, и вокруг сокращения задач связанных с рендерингом.
Вынос в отдельный слой
Существует список триггеров, благодаря которым элементы выносятся в отдельные слои
Если использовать анимацию через изменение left/top
, то вам необходимо перерисовывать всю область на экране. На основном слое будет находится и фон и квадрат, и придется совершать больше работы связанной с редерингом (тайлинг, растеризация и тп)
В случае анимации через transform: translate
- происходит вынос квадрата в отдельный слой, как следствие нужно меньше работы совершить на отрисовку
Про сокращение paint операций
В случае с top/left
запускает создание задач связанных с rendering pipeline
, причем для каждого кадра, то есть это задачи recalculate style, layout, update layer tree, paint, composite layers
Когда-то разработчики из компании Google сделали csstriggers.com, чтобы понять что создает новые задачи в main thread
Если посмотреть на задачи создаваемые с помощью transform: translate
, то main thread практически пустой, по крайней мере вышеупомянутых задач нет. Нет задач — нет новых paint операций
С точки зрения процессов и потоков
Уменьшение задач в main thread это конечно хорошо, но есть еще одна замечательная иллюстрация, взглянув на которую у вас пропадут вопросы, которые вы возможно начали мне писать. Давайте посмотрим на все с точки зрения процессов и потоков!
Если на странице изменится DOM, то мы породим цепочку задач, между 3 процессами участвующими в отрисовке:
В случае с анимацией через transform: translate
цепочка сократится задач и участвующих в ней потоков сократится:
Сопроводительные материалы — How to create high-performance CSS animations — GPU Accelerated Compositing in Chrome — Overview of the RenderingNG architecture
Нашли ошибку или опечатку? Предложите исправление