Оптимизация анимации CSS с помощью will-change
Invite pending
Хочу предоставить вам перевод статьи про оптимизацию CSS трансформаций.
Работа над производительностью CSS может быть весьма интересна. Большое количество факторов, даже css-свойста, которые мы используем, могут сильно повлиять на юзабилити страницы.
Я заметил, что мой сайт (такой простой, казалось бы) имел небольшую проблему с фиксированным фоном. Прокрутка страницы выполняется не так плавно, как я бы этого хотел. Я не помню, чтобы когда я делал этот сайт это было для меня проблемой, но браузеры меняются.
Я решил сменить фиксированный фон на статичный, и все стало отлично работать. Правда я сомневаюсь, что эти изменения вообще кто-нибудь заметил.
Конечно, не каждая проблема связанная с производительностью настолько несущественна и легко решаема.
Проблемы связанные с box-shadow или scroll-jacking часто встречается в проектах, где они требуются для достижения дизайнерских задумок.
С приходом новых CSS-свойств появляется больше сложностей, которые приводят к появлению проблем с производительностью. Браузеры признают, что некоторые CSS-свойства необходимо обрабатывать по-разному, чтобы улучшить производительность.
Например, трансформации (особенно в 3D пространстве) могут обрабатываться GPU, чтобы сделать рендеринг страницы еще быстрее. Также мы бы могли получить прирост в производительности в том случае, когда мы двигаем элемент в 3D пространстве с помощью translateZ, но на самом деле он не меняет своего положения.
Злоупотребляя свойствами, представление о работе CSS-свойств разработчиками браузеров и веб-разработчиками сильно разнится. Это как с float'ами, используемыми для верстки макета. Мы используем свойства для тех вещей, для которых они никогда не предназначались.
Разработчики браузеров приняли решение создать новое свойство, которое было бы направлено конкретно на работу с производительностью, а также сделало представление о её работе более прозрачной для веб-разработчиков.
CSS сейчас имеет свойство will-change, что позволяет сообщить браузеру, какие манипуляции будут происходить с элементом, для того чтобы их оптимизировать.
Свойство will-change обычно используется, чтобы указать, что CSS-свойство будет изменено у конкретного элемента.
В этом случае трансформация над элементом .modal может как произойти, так и не пройзойти, но мы попытались сообщить браузеру о возможных манипуляциях.
Однако, используя это свойство возникает интересный побочный эффект.
Если мы применим к элементу transform:translateZ(0), элемент создаст новый контекст наложения, а в некоторых браузерах также добавит слой в свой собственный поток рендеринга, что даст нам прирост в производительности, чего мы и добиваемся.
Следовательно, используя will-change: transform, браузер создаст новый контекст наложения, независимо от того, применяли мы трансформацию к элементу или нет.
Ключевая вещь на заметку, will-change будет создавать новый контекст наложения только если свойство также создает новый контекст наложения. Поскольку свойство transform создает новый контекст наложения, will-change:transform также создаст новый контекст наложения.
Если вы использовали will-change:display, то новый контекст наложения не будет создан, т.к. ни одно значение свойство display не создает новый контекст наложения.
Давайте лучше посмотрим на еще один пример: opacity. Opacity со значением равным 1 не создает новый контекст наложения, но с меньшим значением (например 0.9) создаст. В то время, как will-change:opacity в любом случае создаст новый контекст наложения.
Не все браузеры поддерживают will-change. Следовательно, в связи с его поведением создания нового контекста наложения, вам необходимо точно указывать CSS-свойства, которые действительно создают новый контекст наложения, для достижения схожих результатов рендеринга.
Скорее всего, если вы играете с наслоением элементов на странице, вы уже используете position и z-index для достижения нужного порядка наложения и следовательно можете не столкнуться с этим, весьма интересным эффектом свойства will-change.
Работа над производительностью CSS может быть весьма интересна. Большое количество факторов, даже css-свойста, которые мы используем, могут сильно повлиять на юзабилити страницы.
Я заметил, что мой сайт (такой простой, казалось бы) имел небольшую проблему с фиксированным фоном. Прокрутка страницы выполняется не так плавно, как я бы этого хотел. Я не помню, чтобы когда я делал этот сайт это было для меня проблемой, но браузеры меняются.
Я решил сменить фиксированный фон на статичный, и все стало отлично работать. Правда я сомневаюсь, что эти изменения вообще кто-нибудь заметил.
Конечно, не каждая проблема связанная с производительностью настолько несущественна и легко решаема.
Проблемы связанные с box-shadow или scroll-jacking часто встречается в проектах, где они требуются для достижения дизайнерских задумок.
С приходом новых CSS-свойств появляется больше сложностей, которые приводят к появлению проблем с производительностью. Браузеры признают, что некоторые CSS-свойства необходимо обрабатывать по-разному, чтобы улучшить производительность.
Например, трансформации (особенно в 3D пространстве) могут обрабатываться GPU, чтобы сделать рендеринг страницы еще быстрее. Также мы бы могли получить прирост в производительности в том случае, когда мы двигаем элемент в 3D пространстве с помощью translateZ, но на самом деле он не меняет своего положения.
Злоупотребляя свойствами, представление о работе CSS-свойств разработчиками браузеров и веб-разработчиками сильно разнится. Это как с float'ами, используемыми для верстки макета. Мы используем свойства для тех вещей, для которых они никогда не предназначались.
Разработчики браузеров приняли решение создать новое свойство, которое было бы направлено конкретно на работу с производительностью, а также сделало представление о её работе более прозрачной для веб-разработчиков.
CSS сейчас имеет свойство will-change, что позволяет сообщить браузеру, какие манипуляции будут происходить с элементом, для того чтобы их оптимизировать.
Свойство will-change обычно используется, чтобы указать, что CSS-свойство будет изменено у конкретного элемента.
.modal {
will-change: transform;
}
В этом случае трансформация над элементом .modal может как произойти, так и не пройзойти, но мы попытались сообщить браузеру о возможных манипуляциях.
Однако, используя это свойство возникает интересный побочный эффект.
Если мы применим к элементу transform:translateZ(0), элемент создаст новый контекст наложения, а в некоторых браузерах также добавит слой в свой собственный поток рендеринга, что даст нам прирост в производительности, чего мы и добиваемся.
Следовательно, используя will-change: transform, браузер создаст новый контекст наложения, независимо от того, применяли мы трансформацию к элементу или нет.
Ключевая вещь на заметку, will-change будет создавать новый контекст наложения только если свойство также создает новый контекст наложения. Поскольку свойство transform создает новый контекст наложения, will-change:transform также создаст новый контекст наложения.
Если вы использовали will-change:display, то новый контекст наложения не будет создан, т.к. ни одно значение свойство display не создает новый контекст наложения.
Давайте лучше посмотрим на еще один пример: opacity. Opacity со значением равным 1 не создает новый контекст наложения, но с меньшим значением (например 0.9) создаст. В то время, как will-change:opacity в любом случае создаст новый контекст наложения.
Поддержка браузерами
Не все браузеры поддерживают will-change. Следовательно, в связи с его поведением создания нового контекста наложения, вам необходимо точно указывать CSS-свойства, которые действительно создают новый контекст наложения, для достижения схожих результатов рендеринга.
Скорее всего, если вы играете с наслоением элементов на странице, вы уже используете position и z-index для достижения нужного порядка наложения и следовательно можете не столкнуться с этим, весьма интересным эффектом свойства will-change.