Хотите сделать анимацию на сайте? Расскажу как сделать это правильно
На протяжении нескольких лет я занимаюсь разработкой веб-интерфейсов. И всё чаще в дизайн начинают приходить веб-анимации.
Цель статьи: рассказать разработчикам, собирающимся работать с анимациями, о том, что не обязательно использовать какие-то специальные JS библиотеки, которые волшебным образом решают проблемы с анимацией. По большей части, можно полностью обходиться современными возможностями браузеров, такими как GPU Rendering и CSS3 Spec.
В разработке анимаций нет «идеального решения», кроме того приходится тратить часть времени на их тестирование и оптимизацию. Но за продолжительное время работы с ними был придуман ряд принципов дизайна и разработки, которые, ИМХО, приводят к хорошим анимациям. Эти методы позволят вам получить на странице гладкое поведение, обеспечить работу во всех современных браузерах (конечно, мобильных и десктопных), и — самое главное — простых в поддержке.
Технологии и способ внедрения может немного различаться для всех, но общие принципы должны быть полезны практически в любой ситуации.
Что же такое анимация?
Анимации существовали еще до появления интернета, а сделать её красивой — занимало времени примерно столько же, сколько сейчас нужно для освоения фронтенда. Но тем не менее, существуют некоторые ограничения и трудности для их использования в интернете.
Для плавной 60 fps картинки каждый кадр должен быть отрендерен менее, чем за 16 мс. Это не большое количество времени, поэтому нужно искать эффективные способы рендеринга каждого кадра для «гладкой» картинки.
Есть множество способов достичь анимации в вебе. Один из способов – кинополоска (filmstrip), подход придуманный задолго до первых страниц, при котором немного другой кадр, нарисованный вручную, сменяется.
Таким подходом пользуется Apple на своих промо-страницах.
Твиттер так же недавно использовал этот подход для своей новой анимации лайка, перелистывая спрайт кадров.
Да, такой эффект можно повторить CSS-анимациями множеством крошечных элементов, либо SVG анимациями, но это было бы неоправданно сложным и, вполне вероятно, не так гладко бы выглядело.
В большинстве случаев, вы захотите использовать CSS переходы для автоматической анимации элемента при его изменении. Эта техника называется «tweening» — переход между двумя элементами (beTWEEN). Преимущество данного подхода в том, что он легко отменяется или возвращается без необходимости строить логику. Это идеально подходит для анимаций в стиле «сделал и забыл». Например, для появления секций или простых взаимодействий, как hover
и т. д.
Дополнительное чтение: Все, что вы должны знать о CSS анимациях.
В других случаях keyframe-based анимации могут стать идеальным решением для непрерывной работы деталей фона. Например, вращающийся loader.
Итак, вот несколько советов, которые должны улучшить производительность ваших анимаций:
1. Не меняйте никаких свойств, кроме opacity и transform
Даже если ты думаешь, что это нормально – не надо :)
Один этот принцип может стоить вам 80% производительности вашего проекта, в т.ч. на мобильных устройствах. Вы, наверное, уже слышали этот принцип раньше – это часто упоминается во всех мануалах, но далеко не каждый веб-разработчик её соблюдает.
Это правило довольно просто выполняется и как только вы привыкнете к этому, то даже перестанете задумываться. Например, если вы хотите уменьшить размер элемента – не надо трогать его width
и height
, когда можно использовать transform: scale().
А если вдруг вы хотите передвинуть элемент – вполне можно обойтись без изменения марджинов тем же трансформом.
Почему это работает?
Для человека изменение ширины, отступа или других свойств может показаться несущественным и даже предпочтительным, так как эти свойства проще. Но с точки зрения того, что браузер должен сделать "под капотом" для правильного изменения этих свойств – это огромная работа.
Команды браузеров проделали огромную работу по оптимизации работы transform
и данное решение вполне простое и эффективное, ведь в множестве случаев позволяет использовать преимущества видеокарты без ре-рендера элементов. Да, вы можете использовать border-radius
, загрузить кучу изображений и поставить каждой размытие с box-shadow,
но делайте это лишь один раз, при первоначальном рендере страницы. После этого при каждом изменении упомянутых выше свойств браузер насчет перерасчёт всей страницы, что может повлиять на появление лагов.
Дополнительное чтение: Передвигайте элементы через translate (Paul Irish)
2. Скрывайте содержимое правильно
Используйте pointer-events: none
, когда убираете прозрачность у элементов.
Давным-давно, когда анимации делали через jQuery animate(),
большая часть проблем была связана с кликабельностью элементов во время анимаций, так как все анимации были завязаны на изменении opacity и дальнейшем display: none
у элементов. В итоге из-за рассинхронизации, на страницах был момент, когда есть большой пустой (прозрачный) кликабельный блок при анимации скрытия/появления элемента. А после каждой анимации приходилось делать колбек.
CSS-свойство pointer-events
в основном используется для того, чтобы элемент переставал реагировать на клики или любые другие взаимодействия. Его легко можно включить/выключить с помощью CSS, не прерывая анимацию и не влияя на рендеринг элемента. Это прекрасно работает с абсолютно позиционированными элементами, потому что вы можете быть уверены, что они не оказывает абсолютно никакого влияния на странице.
3. Не анимируйте все единовременно
Лучше постройте композицию.
Одна анимация может быть гладкой сама по себе, но множество таких анимаций запущенных единовременно могут привести к проблемам с композицией. Поэтому важно их правильно спланировать.
Лучше всего распределить время так, чтобы одновременно не выполнялось более 3 анимаций на сайте. Если на вашей странице не одна анимация – стоит задуматься над их композицией. Хоть, каждая анимация – это отдельный элемент, вместе они образуют систему. И у любого элемента система должно быть своё направление и своё время исполнения, чтобы не ломать остальное.
В Material Design гайдах от Гугла концепция правильно выстроенных анимаций называется хореографией, хоть это и танцевальный термин.
Это не единственный способ правильной работы над анимациями, а та часть, над которой нужно думать при разработке и тестировать.
Дополнительное чтение: Material Design – Motion.
4. Незначительные задержки перехода улучшают общую композицию анимаций
Композиция анимаций действительно важна и потребует много экспериментов, чтобы почувствовать себя правильно. Однако код для этого не должен быть очень сложным. Обычно, можно изменением одного класса (часто это может быть класс на body
), вызвать кучу переходов, каждый из которых будет иметь свои собственные переменные задержки перехода, чтобы завершиться в нужное время. С точки зрения кода, вы просто должны побеспокоиться об одном изменении состояния, а не поддерживать десятки таймингов внутри вашего JS.
Важно распределить анимации в серии так, чтобы это было похоже на непрерывный поток, а не на цепочку отдельных вещей.
Пример кода
Есть пара простых приёмов для анимации серии элементов – особенно если это список. Если в нём статическое количество элементов, то можно обойтись всего лишь SASS миксином.
@for $i from 1 through 7 {
&:nth-child(#{$i}) {
.loaded & {
.text {
transition-delay: 500 + (42ms * $i);
}
}
}
}
Для длинных списков или динамического контента, тайминги можно устанавливать с помощью JS и таких же циклов по каждому элементу.
const baseDelay = 350
const randomDelay = 64
document.querySelectorAll('.reports li').forEach((item, index) => {
setTimeout(() => {
item.classList.add('showing')
}, baseDelay + randomDelay * index)
})
Обычно в данных циклах есть две переменные: базовая задержка и затем временная задержка между каждым элементом. Это хитрый баланс, который нужно найти, но когда вы достигнете необходимых значений, то быстро почувствуете себя Motion-гением.
6. Используйте глобальные модификаторы для замедленного режима
Но не забывайте после этого обратно ускорить :)
В разработке анимаций правильно подобранное время – это всё. Лишь 20% времени вы будете что-то создавать и реализовывать, а оставшиеся 80% будут заключаться в поиске правильных параметров и анимаций, чтобы все анимации были синхронизированы и плавными.
Особенно, когда вы работаете над хореографией нескольких элементов и пытаетесь получить производительность и параллельность на странице, видеть всё это в замедленном режиме гораздо проще.
Вне зависимости от синтаксиса написания ваших анимаций (CSS, SASS, JS) это не так тяжело реализовать с помощью небольшой помощи математики и использования переменных.
Например, если анимация имеет подвисания даже на скорости в 10x раз меньше, то возможно вы делаете что-то не так. Если же при замедлении в 50x раз анимация идёт плавно, то остаешься лишь определить максимальную скорость, при которой она будет работать. Может быть трудно заметить проблемы в производительности на полной скорости, но если вы замедлите все анимации, то проблемы становятся очевидными.
6. Сетевые запросы могут вызывать лаги
Поэтому не забывайте о предзагрузке данных или откладывайте большие HTTP запросы
Изображения являются большим виновником данного пункта, будь то несколько больших картинок (фоновые изображения) или множество маленьких (иконки, аватарки и т.д.), или же просто большое количество контента.
Когда страница загружается первый раз – происходит инициализация и загрузка множества вещей. Наличие аналитики, рекламы и других сторонних скриптов делает это ещё хуже. Иногда задержка всех анимаций всего на несколько сотых мс после загрузки творит чудеса с производительностью.
Не усложняйте оптимизацию данного пункта, пока это не станет необходимым, но сложная страница может потребовать очень точных задержек и таймингов контента для бесперебойной работы.
В общем и целом, вам нужно сначала загрузить как можно меньше данных, а затем продолжить загрузку остальной части страницы после завершения первых анимаций (к примеру, первый экран лендинга).
На страницах с большим количеством контента работа по загрузке этих данных может быть очень требовательной. Анимация, которая хорошо работает с статическим контентом, может начать разваливаться если в неё загружать динамические данные. Если вам кажется, что анимация должна работать, а стабильно работает она не всегда – я бы посоветовал проверить во время выполнения вкладку Network в браузере, чтобы убедиться, что вы не занимаетесь загрузкой данных и другой сложной работой в браузере в это время.
7. Не привязывайте анимацию напрямую к скроллу
Вроде идея звучит круто, но это не совсем так
За последние несколько лет анимация на основе прокрутки иногда приобретает большую популярность, особенно с использованием параллакса или некоторых других специальных эффектов. Являются ли эти анимации хорошим дизайном, остается предметом споров, но есть лучшие и худшие способы их технической реализации.
Достаточно эффективный способ сделать что-то из этой категории – рассматривать достижение определенного расстояния прокрутки как событие - и просто запускать анимацию один раз. Если вы действительно не знаете, что делаете, я бы посоветовал избегать этой категории, поскольку в ней очень легко ошибиться и ее очень трудно поддерживать.
Худшим вариантом является создание собственного функционала скролла. Так называемый scrolljacking.
Пожалуйста, не делайте этого на своих сайтах.
Это одно из тех правил, которые особенно полезны на мобильных устройствах. Так же, кастомный скролл – это анти user experience паттерн.
Если же в вашем проекте это обязательно – сначала создайте быстрый прототип, чтобы убедиться в нормальной производительности вашего решения, перед тем как тратить время на разработку анимаций.
Дополнительное чтение: Scrolljacking – кошмар для вашего UX
8. Проверяйте на мобильных как можно раньше и чаще
Большинство веб-сайтов создаются на компьютере и, вероятно, чаще всего тестируются на том же компьютере, на котором они разработаны. Таким образом, мобильные возможности и производительность анимаций часто остаются в тени. Некоторые технологии (например, canvas) или методы анимаций могут не работать на мобильных устройствах.
Однако, при правильной разработке и оптимизации (см. 1 пункт) работа на мобильных устройствах может быть даже более плавной, чем на компьютере. Когда-то мобильная оптимизация была очень сложной задачей, но теперь новые iPhone работают быстрее, чем большинство ноутбуков! Если вы следовали всем предыдущим советам, то вполне возможно, что у вас сразу же появится отличная мобильная производительность.
Мобильный UX будет большой и важной частью практически любого сайта. Это может показаться странным, но я бы посоветовал вам просматривать ваш сайт какое-то время только с смартфона. Принуждение к использованию только мобильной версии не должно восприниматься как наказание.
Продолжайте улучшать дизайн и повышать производительность мобильной версии, пока она не станет такой же безупречной и удобной, как десктопная версия вашего сайта.
9. Тестируйте на разных устройствах
Размер экрана, плотность и устройство могут иметь большое значение
Помимо мобильных устройств и компьютеров существует множество факторов, которые могут существенно повлиять на производительность. Например, является ли экран ретиной, общее количество пикселей в окне, какая ОС установлена и т.д.
Несмотря на то, что Chrome, Safari и Edge являются браузерами на основе Webkit с аналогичным синтаксом, у каждого из них есть свои особенности.
Каждое обновление Chrome может что-то исправить и внести новые ошибки, поэтому нужно постоянно следить за изменениями.
Я регулярно переключаюсь между своим настольным ПК на Windows 10, рабочим Macbook Pro и iPad с iPhone. Каждый цикл переключения по своим сайтам может выявить проблемы и улучшения, которые необходимо внести – часто это производительность оптимизации, но также это могут быть общий дизайн сайта, шрифты, плотность информации и т.д.
Медиа-запросы могут быть действительно мощными инструментами для работы с этими разными сегментами. Изменение стилей в зависимости от ширины экрана – типичное использование медиа-запросов, но их также можно использовать для таргетинга по плотности пикселей или другим свойствам.
Источник
Надеюсь, что эти техники будут полезны вам в разработке ваших следующих проектов, а так же в поддержке текущих. Ещё больше контента по разработке, дизайну в моём авторском Telegram канале по разработке – Вёрстка Жизни (life_verstka). Удачи!