UfoStation

Не делайте анимации через изменение 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 animationsGPU Accelerated Compositing in ChromeOverview of the RenderingNG architecture

Нашли ошибку или опечатку? Предложите исправление