В этом руководстве вы узнаете, как создавать высокопроизводительные CSS-анимации.

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

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

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

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

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

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

.animate {  animation: slide-in 0.7s both;}@keyframes slide-in {  0% {    transform: translateY(-1000px);  }  100% {    transform: translateY(0);  }}

Элементы также можно поворачивать, в примере ниже на 360 градусов.

.animate {  animation: rotate 0.7s ease-in-out both;}@keyframes rotate {  0% {    transform: rotate(0);  }  100% {    transform: rotate(360deg);  }}

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

Чтобы изменить размер элемента, используйте scale ключевое слово value 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;  }}

Найдите примеры копирования и вставки различных анимаций в Animista.

Избегайте свойств, которые запускают layout или paint #

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

Предупреждение

Если вам необходимо использовать свойство, которое запускает layout или paint, маловероятно, что вы сможете сделать анимацию плавной и высокопроизводительной.

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

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

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

Внимание

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

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

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

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

Для получения дополнительной информации и примеров правильного использования will-changeпрочитайте Все, что вам нужно знать о свойстве CSSwill-change.

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

Отлаживать медленные или неаккуратные анимации #

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

Проверьте, запускает ли анимация макет #

Анимация, которая перемещает элемент, используя что-то другое, чемtransform, вероятно, будет медленной. В следующем примере я добился того же визуального результата, анимируя topи left, и используя transform.

Не

.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));  }}

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

Chrome DevTools #

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

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

Сводная панель показывает 37 мс для рендеринга и 79 мс для рисования.

Пример анимации с верхним левым углом вызывает работу рендеринга.

На панели "Сводка" отображаются нулевые значения для рендеринга и рисования.

Пример анимации с преобразованием не вызывает работы по рендерингу.

Firefox DevTools #

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

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

Если вы видите записи для стиля пересчета, то браузеру приходится начинать с начала каскада рендеринга.

Проверьте, не отбрасывает ли анимация кадры #

  1. Откройте вкладку рендеринга Chrome DevTools.
  2. Установите флажок FPS meter (Счетчик кадров в секунду).
  3. Следите за значениями во время выполнения анимации.

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

Счетчик кадров в секунду показывает, что было удалено 50% кадров

Пример анимации с верхним левым углом приводит к удалению 50% кадров

Счетчик кадров в секунду показывает, что был удален только 1% кадров

Пример анимации с преобразованием приводит к удалению только 1% кадров.

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

Когда дело доходит до рисования, некоторые вещи стоят дороже, чем другие. Например, все, что связано с размытием (например, тень), будет рисовать дольше, чем рисование красного прямоугольника. Однако с точки зрения CSS это не всегда очевидно: background: red;и box-shadow: 0, 4px, 4px, rgba(0,0,0,0.5);не обязательно выглядит так, будто они имеют совершенно разные характеристики производительности, но это так.

Browser DevTools can help you to identify which areas need to be repainted, and performance issues related to painting.

Chrome DevTools #

  1. Open the Rendering tab of Chrome DevTools.
  2. Select Paint Flashing.
  3. Move the pointer around the screen.

Элемент пользовательского интерфейса, выделенный зеленым для демонстрации, будет перерисован

В этом примере из Google Maps вы можете увидеть элементы, которые будут перерисованы.

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

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

Firefox DevTools #

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

Заключение #

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

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

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