Почему некоторые анимации медленные?

Современные браузеры могут дешево анимировать два свойства CSS: transform и opacity . Если вы анимируете что-нибудь еще, скорее всего, вам не удастся добиться плавных и плавных 60 кадров в секунду (FPS). Этот пост объясняет, почему это так.

Производительность анимации и частота кадров

Широко распространено мнение, что частота кадров 60 кадров в секунду является целевой при анимации чего-либо в Интернете. Эта частота кадров обеспечит плавность анимации. В Интернете фрейм — это время, необходимое для выполнения всей работы по обновлению и перерисовке экрана. Если каждый кадр не завершается в течение 16,7 мс (1000 мс / 60 ≈ 16,7), пользователи ощутят задержку.

Конвейер рендеринга

Чтобы отобразить что-либо на веб-странице, браузер должен выполнить следующие последовательные шаги:

  1. Стиль : рассчитайте стили, применимые к элементам.
  2. Макет : создайте геометрию и положение для каждого элемента.
  3. Краска : Заполните пиксели каждого элемента слоями .
  4. Композитный : выведите слои на экран.

Эти четыре шага известны как конвейер рендеринга браузера.

Когда вы анимируете что-то на уже загруженной странице, эти шаги придется повторить. Этот процесс начинается с шага, который необходимо изменить, чтобы разрешить анимацию.

Как упоминалось ранее, эти шаги являются последовательными . Например, если вы анимируете что-то, что меняет макет, шаги рисования и композиции также придется выполнить заново. Поэтому анимация чего-то, что меняет макет, обходится дороже, чем анимация чего-то, что меняет только композицию.

Анимация свойств макета

Изменения макета включают расчет геометрии (положения и размера) всех элементов, на которые влияют изменения. Если вы измените один элемент, возможно, потребуется пересчитать геометрию других элементов. Например, если вы измените ширину элемента <html> , это может повлиять на любой из его дочерних элементов. Из-за того, что элементы переполняются и влияют друг на друга, изменения ниже по дереву иногда могут привести к тому, что расчеты макета будут выполняться вплоть до самого верха.

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

Анимация свойств краски

Отрисовка — это процесс определения порядка отображения элементов на экране. Часто это самая продолжительная из всех задач в конвейере.

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

Анимация составных свойств

Композитинг — это процесс разделения страницы на слои, преобразования информации о том, как страница должна выглядеть в пиксели (растеризация), и объединения слоев для создания страницы (композитинг).

Вот почему свойство opacity включено в список вещей, которые легко анимировать. Пока это свойство находится на отдельном слое, его изменения могут обрабатываться графическим процессором на этапе композиции. Браузеры на основе Chromium и WebKit создают новый слой для любого элемента, который имеет CSS-переход или анимацию opacity .

Что такое слой?

Размещая объекты, которые будут анимированы или перенесены на новый слой, браузеру нужно перерисовать только эти элементы, а не все остальное. Возможно, вы знакомы с концепцией слоя Photoshop, который содержит множество элементов, которые можно перемещать вместе. Слои рендеринга браузера аналогичны этой идее.

Хотя браузер хорошо справляется с принятием решений о том, какие элементы должны быть на новом слое, если он пропускает один из них, есть способы принудительно создать слой. Вы можете узнать об этом в разделе «Как создавать высокопроизводительную анимацию» . Однако создавать новые слои следует с осторожностью, поскольку каждый слой использует память. На устройствах с ограниченной памятью создание новых слоев может вызвать более серьезную проблему с производительностью, чем та, которую вы пытаетесь решить. Кроме того, текстуры каждого слоя необходимо загрузить в графический процессор. Поэтому вы вполне можете столкнуться с ограничениями пропускной способности между процессором и графическим процессором.

CSS и производительность JavaScript

Вы можете задаться вопросом: что лучше с точки зрения производительности использовать для анимации CSS или JavaScript?

Анимации на основе CSS и веб-анимации (в браузерах, поддерживающих API) обычно обрабатываются в потоке, известном как поток компоновщика . Это отличается от основного потока браузера, где выполняются стили, макет, рисование и JavaScript. Это означает, что если браузер выполняет какие-то ресурсоемкие задачи в основном потоке, эти анимации могут продолжать работать без прерывания.

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

Если какая-либо анимация запускает рисование, макет или и то, и другое, для выполнения работы потребуется основной поток. Это справедливо как для анимации CSS, так и для JavaScript, а затраты на макетирование или рисование, скорее всего, затмят любую работу, связанную с выполнением CSS или JavaScript, что сделает вопрос спорным.