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

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

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

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

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

transform

Browser Support

  • Chrome: 36.
  • Край: 12.
  • Firefox: 16.
  • Сафари: 9.

Source

opacity

Browser Support

  • Chrome: 1.
  • Край: 12.
  • Firefox: 1.
  • Сафари: 2.

Source

will-change

Browser Support

  • Chrome: 36.
  • Край: 79.
  • Firefox: 36.
  • Safari: 9.1.

Source

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

Для перемещения элемента используйте ключевые слова 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 , можно установить transform: translateZ(0) .

Отладка медленных или некорректно работающих анимаций

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

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

Анимация, в которой элемент перемещается с помощью чего-либо, кроме 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));
  }
}

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

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

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

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

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

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

В инструментах разработчика Firefox функция «Каскадная диаграмма» помогает понять, на какие задачи браузер тратит больше всего времени.

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

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

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

  1. Откройте вкладку «Рендеринг» в инструментах разработчика Chrome.
  2. Включите флажок «Измерить частоту кадров» .
  3. Следите за значениями во время выполнения анимации.

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

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

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

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

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

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

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

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

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

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

Анимация на этапе композитинга.

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

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

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