Эта статья — перевод оригинальной статьи "A case study on scroll-driven animations performance".

Также я веду телеграм канал “Frontend по-флотски”, где рассказываю про интересные вещи из мира разработки интерфейсов.

Что нового в анимации на основе скрола?

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

Раньше единственным способом создания анимации на основе скрола страницы, было реагирование на событие прокрутки в главном потоке. Это приводило к двум основным проблемам:

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

  2. Анимации основного потока подвержены помехам.

Это делает невозможным или очень сложным создание производительной анимации, синхронизированной со скролом.

Мы представляем новый набор API для поддержки анимации на основе скрола, которую можно использовать из CSS или JavaScript. API старается использовать как можно меньше ресурсов главного потока, что значительно упрощает реализацию анимации с прокруткой, а также делает её более плавной. В настоящее время API анимации поддерживается в следующих браузерах:

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timeline#browser_compatibility

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

CSS API против классического JavaScript

Следующий пример прогресс-бара построен с использованием приемов JavaScript.

Документ реагирует на каждое событие scroll, вычисляя, на сколько процентов от значения scrollHeight прокрутил пользователь.

document.addEventListener("scroll", () => {
  var winScroll = document.body.scrollTop || document.documentElement.scrollTop;
  var height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
  var scrolled = (winScroll / height) * 100; 
  document.getElementById("progress").style.width = scrolled + "%";
})

В следующем демонстрационном примере показан тот же прогресс-бар, использующий новый API с CSS.

@keyframes grow-progress {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

#progress {
  animation: grow-progress auto linear forwards;
  animation-timeline: scroll(block root);
}

Новая CSS-функция animation-timeline автоматически преобразует позицию в диапазоне прокрутки в процентное соотношение прогресса, тем самым выполняя всю тяжелую работу.

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

function someHeavyJS() {
  let time = 0;
  window.setInterval(function () {
    time++;
    for (var i = 0; i < 1e9; i++) {
      result = i;
    }
    console.log(time)
  }, 100);
}

Как и следовало ожидать, классическая JavaScript-версия становится неаккуратной и вялой из-за перегрузки ресурсов основного потока. С другой стороны, CSS-версия совершенно не подвержена влиянию тяжелой работы JavaScript и может реагировать на действия пользователя при скроле.

CodePen с классической JS реализацией

CodePen с использованием нового API (Chrome 115+)

Использование CPU в DevTools совершенно иное, как видно из следующих скриншотов.

На демо ниже видно применение анимации на основе скрола, созданной CyberAgent. Можно заметить, что фотография исчезает по мере прокрутки.

Демо

Новый JavaScript API для анимации с прокруткой в сравнении с классической JavaScript реализацией

Преимущества нового API не ограничиваются только CSS. Вы можете создавать плавные анимации прокрутки и с помощью JavaScript. Взгляните на следующий пример:

const progressbar = document.querySelector('#progress');
progressbar.style.transformOrigin = '0% 50%';
progressbar.animate(
  {
    transform: ['scaleX(0)', 'scaleX(1)'],
  },
  {
    fill: 'forwards',
    timeline: new ScrollTimeline({
      source: document.documentElement,
    }),
  }
);

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

Кроме того, новый API работает совместно с существующими Web Animations API (WAAPI) и CSS Animations API, позволяя реализовать наглядную анимацию на основе скрола.

CodePen демо с классической JS реализацией

CodePen демо с использование нового JS API

Другие примеры и ресурсы

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

Если вы хотите узнать больше о новой анимации с прокруткой, ознакомьтесь с этой статьей и докладом на I/O 2023!

Комментарии (2)


  1. edo1h
    23.07.2023 22:03
    +1

    Это отличный способ удержать пользователей и сделать сайт более привлекательным

    серьёзно?


    1. qmzik Автор
      23.07.2023 22:03

      Я думаю автор имел ввиду более обобщённо про анимации, а не про конкретный пример из статьи