Как создавать высокопроизводительную CSS-анимацию

Это руководство научит вас создавать высокопроизводительную CSS-анимацию.

См. раздел Почему некоторые анимации работают медленно? изучить теорию, лежащую в основе этих рекомендаций.

Совместимость с браузером

Все свойства CSS, рекомендуемые в этом руководстве, имеют хорошую кросс-браузерную поддержку.

transform

Поддержка браузера

  • 36
  • 12
  • 16
  • 9

Источник

opacity

Поддержка браузера

  • 1
  • 12
  • 1
  • 2

Источник

will-change

Поддержка браузера

  • 36
  • 79
  • 36
  • 9.1

Источник

Переместить элемент

Чтобы переместить элемент, используйте значения ключевых слов translate или rotation свойства transform .

Например, чтобы переместить элемент в поле зрения, используйте translate .

.animate {
  animation: slide-in 0.7s both;
}

@keyframes slide-in {
  0% {
    transform: translateY(-1000px);
  }
  100% {
    transform: translateY(0);
  }
}

Используйте rotate , чтобы ��р��щать элементы. В следующем примере элемент поворачивается на 360 градусов.

.animate {
  animation: rotate 0.7s ease-in-out both;
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}

Изменение размера элемента

Чтобы изменить размер элемента, используйте значение ключевого слова scale свойства transform .

.animate {
  animation: scale 1.5s both;
}

@keyframes scale {
  50% {
    transform: scale(0.5);
  }
  100% {
    transform: scale(1);
  }
}

Изменение видимости элемента

Чтобы показать или скрыть элемент, используйте opacity .

.animate {
  animation: opacity 2.5s both;
}

@keyframes opacity {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

Избегайте свойств, которые запускают макет или рисование.

Прежде чем использовать какое-либо свойство CSS для анимации (кроме transform и opacity ), определите влияние этого свойства на конвейер рендеринга . Избегайте любого свойства, которое запускает макет или рисование, если это не абсолютно необходимо.

Принудительное создание слоя

Как описано в разделе «Почему некоторые анимации работают медленно?» размещение элементов на новом слое позволяет браузеру перерисовывать их без необходимости перерисовывать остальную часть макета.

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

В CSS вы можете применить will-change к любому селектору:

body > .sidebar {
  will-change: transform;
}

Однако спецификация предполагает, что вам следует делать это только для элементов, которые всегда могут измениться. Например, это может быть справедливо для боковой панели, которую пользователь может сдвигать и выдвигать. Для элементов, которые изменяются нечасто, мы рекомендуем применять will-change с помощью JavaScript, когда изменение может произойти. Обязательно дайте браузеру достаточно времени для выполнения необходимой оптимизации и удалите свойство, когда изменение прекратится.

Если вы принудительно создаете слой в браузере, который не поддерживает will-change (скорее всего, в Internet Explorer), вы можете установить transform: translateZ(0) .

Отладка медленной или глючной анимации

В Chrome DevTools и Firefox DevTools имеется множество инструментов, которые помогут вам выяснить, почему ваша анимация работает медленно или с ошибками.

Проверьте, вызывает ли анимация макет

Анимация, которая перемещает элемент с помощью чего-то другого, кроме transform , скорее всего, будет медленной. В следующем примере анимация с использованием transform сравнивается с анимацией с использованием 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);
  }
}
Делать
.box {
  position: absolute;
  top: 10px;
  left: 10px;
  animation: move 3s ease infinite;
}

@keyframes move {
  50% {
     transform: translate(calc(90vw - 200px), calc(90vh - 160px));
  }
}

Вы можете проверить это на следующих двух примерах Glitch и изучить производительность с помощью DevTools.

Инструменты разработчика Chrome

  1. Откройте панель «Производительность» .
  2. Записывайте производительность во время выполнения анимации.
  3. Проверьте вкладку «Сводка» .

Если вы видите ненулевое значение для параметра «Рендеринг» на вкладке «Сводка» , это может означать, что ваша анимация заставляет браузер работать с макетом.

На панели «Сводка» отображается 37 мс для рендеринга и 79 мс для рисования.
Пример анимации с левым верхом вызывает работу рендеринга.
На панели «Сводка» отображаются нулевые значения для рендеринга и рисования.
Пример анимации с преобразованием не вызывает работу по рендерингу.

Инструменты разработчика Firefox

В Firefox DevTools водопад может помочь вам понять, на что браузер тратит время.

  1. Откройте панель «Производительность» .
  2. Начните записывать исполнение во время анимации.
  3. Остановите запись и проверьте вкладку «Водопад» .

Если вы видите записи для Recalculate Style , это означает, что браузер должен вернуться к ��ачалу каскада рендеринга для рендеринга анимации.

Проверьте наличие пропущенных кадров

  1. Откройте вкладку «Рендеринг» в Chrome DevTools.
  2. Установите флажок счет��ика FPS .
  3. Следите за значениями во время работы анимации.

Обратите внимание на метку «Кадры» в верхней части пользовательского интерфейса счетчика FPS . Это показывает такие значения, как 50% 1 (938 m) dropped of 1878 . Высокопроизводительная анимация имеет высокий процент, например 99% , что означает, что пропускается мало кадров и анимация выглядит плавной.

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

Проверьте, вызывает ли анимация рисование

Отрисовка некоторых свойств браузеру обходится дороже, чем другие. Например, рисование всего, что связано с размытием (например, тени), занимает больше времени, чем рисование красного прямоугольника. Эти различия не всегда очевидны в CSS, но инструменты разработчика браузера могут помочь вам определить, какие области необходимо перерисовать, а также другие проблемы с производительностью, связанные с отрисовкой.

Инструменты разработчика Chrome

  1. Откройте вкладку «Рендеринг» в Chrome DevTools.
  2. Выберите «Краска мигает» .
  3. Перемещайте указатель по экрану.
Элемент пользовательского интерфейса, выделенный зеленым, чтобы продемонстрировать, что он будет перерисован.
В этом примере из Google Maps вы можете увидеть перерисовываемые элементы.

Если вы видите, что весь экран мигает или выделены области, которые, по вашему мнению, не должны меняться, исследу��те дальше.

Если вам нужно определить, вызывает ли определенное свойство проблемы с производительностью, связанные с рисованием, вам может помочь профилировщик рисования в Chrome DevTools.

Инструменты разработчика Firefox

  1. Откройте «Настройки» и добавьте кнопку «На панели инструментов» для переключения мигания краски .
  2. На странице, которую вы хотите проверить, включите кнопку и переместите мышь или прокрутите, чтобы увидеть выделенные области.

Заключение

Там, где это возможно, ограничьте анимацию opacity и transform , чтобы анимация оставалась на этапе композиции пути рендеринга. Используйте DevTools, чтобы проверить, на какой этап пути влияет ваша анимация.

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

Используйте свойство will-change с осторожностью и только в том случае, если у вас возникнут проблемы с производительностью.