Почему перемещать элементы с помощью translate лучше, чем с position:absolute top/left

от автора

Для перемещения элемента по экрану есть два основных способа:

  • CSS 2D-преобразования и translate();
  • position:absolute и изменение top/left.

Крис Койер недавно писал, почему лучше и логичнее использовать translate (это быстрее, и свойство position имеет большее отношение к вёрстке, а не к визуальным эффектам и анимации, в отличие от translate).

Я хочу расширить его ответ и привести несколько хороших примеров. Я записал скринкаст, в котором помощью Chrome DevTools timline рассматриваю различия между этими подходами с точки зрения производительности, особенностей рендеринга и композитинга на GPU.

Если вам нужна сокращённая текстовая версия — продолжайте читать.

Начнём с примеров, которые приводил Крис:

Это вполне корректные примеры, но они настолько просты, что оба варианта выглядят отлично. Мы возьмем что-то более сложное, чтобы как следует нагрузить браузер, и тогда разница станет гораздо заметнее (спасибо joshua за иконку макбука)

Вот так гораздо лучше. Но сначала сделаем небольшое отступление.

Привязка к пикселям

На демо видно, что верхний край макбука выглядит чётче на примере с top/left (а статья вроде бы о том, что translate лучше. Замечательно!) Это происходит из-за того, что абсолютное позиционирование привязывается к позициям пикселей, а translate использует субпиксельную интерполяцию.

Один из разработчиков подсистемы аппаратного ускорения Chrome, Джеймс Робинсон, называет это «дабстеп-эффектом», так как элементы словно вибрируют от низких частот во время движения. Если сделать смещение по одной из осей маленьким, всего в три пикселя, разница становится очень заметной:

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

Вернёмся к производительности

Если открыть timeline в инструментах разработчика Chrome, эти два примера будут выглядеть совершенно по-разному:

Вариант с top/left тратит очень много времени на отрисовку, и движение получается более дёрганым. В стилях прописаны крупные тени, а фон представляет собой сложный градиент, и всё это обсчитывается на CPU. С другой стороны, translate рисует макбук на отдельном слое, все двух- или трёхмерные преобразования делаются на GPU, что намного быстрее, и позволяет получить более плавное движение.

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

Демо

Вы можете добавить больше слоёв, чтобы эффект был более выраженным. Откройте timeline и поэкспериментируйте:

Рекомендации для анимации

  1. Используйте анимации и переходы CSS, когда возможно. Браузер очень хорошо умеет их оптимизировать.
  2. Если необходимо делать анимацию через JavaScript, используйте requestAnimationFrame вместо setTimeout и setInterval.
  3. Старайтесь не менять стили каждый кадр (как это делалось в jQuery animate()), анимации, заданные декларативно в CSS оптимизируются намного лучше.
  4. Использование 2D-трансформаций вместо абсолютного позиционирования обычно обеспечивает большую частоту кадров за счёт более быстрого рендеринга.
  5. Пользуйтесь timeline, чтобы находить и устранять проблемы с производительностью.
  6. Опции «Show Paint Rects» и «Render Composited Layer Borders» полезны, когда надо узнать, какие именно области перерисовываются.

ссылка на оригинал статьи http://habrahabr.ru/post/163645/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *