Studium przypadku dotyczące wydajności animacji przewijanych

Yuriko Hirota
Yuriko Hirota

Co nowego w animacjach opartych na przewijaniu?

Animacje oparte na przewijaniu to sposób na dodanie interaktywności i wizualnego zainteresowania do witryny lub aplikacji internetowej, wywoływane przez pozycję przewijania użytkownika. Może to być świetny sposób na utrzymanie zaangażowania użytkowników i zwiększenie atrakcyjności wizualnej witryny.

W przeszłości jedynym sposobem na tworzenie animacji opartych na przewijaniu było reagowanie na zdarzenie przewijania w wątku głównym. Powodowało to 2 główne problemy:

  • Przewijanie odbywa się w osobnym wątku, dlatego zdarzenia przewijania są dostarczane asynchronicznie.
  • Animacje w wątku głównym są podatne na zacinanie się.

Uniemożliwia to lub bardzo utrudnia tworzenie wydajnych animacji opartych na przewijaniu, które są zsynchronizowane z przewijaniem.

Wprowadzamy teraz nowy zestaw interfejsów API do obsługi animacji opartych na przewijaniu, których można używać w CSS lub JavaScript. Interfejs API stara się używać jak najmniejszej liczby zasobów wątku głównego, co znacznie ułatwia implementację animacji opartych na przewijaniu i sprawia, że są one znacznie płynniejsze. Interfejs API animacji opartych na przewijaniu jest obecnie obsługiwany w tych przeglądarkach:

Browser Support

  • Chrome: 115.
  • Edge: 115.
  • Firefox Technology Preview: supported.
  • Safari: 26.

Source

This article compares the new approach with the classic JavaScript technique to show just how easy and silky-smooth scroll-driven animations can be with the new API.

Interfejs CSS API animacji opartych na przewijaniu a klasyczny JavaScript

Ten przykład paska postępu jest zbudowany przy użyciu klasycznych technik JavaScript.

Dokument reaguje za każdym razem, gdy wystąpi zdarzenie scroll, aby obliczyć, o ile procent scrollHeight przewinął użytkownik.

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 + "%";
})

Ten przykładowy projekt pokazuje ten sam pasek postępu, ale przy użyciu nowego interfejsu API z CSS.

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

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

Nowa funkcja CSS animation-timeline automatycznie przekształca pozycję w zakresie przewijania na procent postępu, wykonując w ten sposób całą ciężką pracę.

Teraz przejdźmy do ciekawej części – załóżmy, że w obu wersjach witryny zaimplementowano bardzo złożone obliczenia, które zużywają większość zasobów wątku głównego.

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

Jak można się było spodziewać, klasyczna wersja JavaScript staje się zacinająca i powolna ze względu na przeciążenie zasobów wątku głównego. Z drugiej strony, wersja CSS jest całkowicie odporna na intensywną pracę JavaScriptu i może reagować na interakcje użytkownika związane z przewijaniem.

Zużycie procesora jest zupełnie inne w Narzędziach deweloperskich, jak pokazują te zrzuty ekranu.

Porównanie wątku głównego.

Ten przykładowy projekt pokazuje zastosowanie animacji opartej na przewijaniu utworzonej przez CyberAgent. Widać, że podczas przewijania zdjęcie stopniowo się pojawia.

Nowy interfejs JavaScript API animacji opartych na przewijaniu a klasyczny JavaScript

Zalety nowego interfejsu API nie ograniczają się tylko do CSS. Możesz też tworzyć płynne animacje oparte na przewijaniu za pomocą JavaScriptu. Spójrz na ten przykład:

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,
    }),
  }
);

Umożliwia to utworzenie tej samej animacji paska postępu, która jest pokazana w poprzednim przykładzie CSS, przy użyciu tylko JavaScriptu. Technologia bazowa jest taka sama jak w przypadku wersji CSS. Interfejs API stara się używać jak najmniejszej liczby zasobów wątku głównego, co sprawia, że animacje są znacznie płynniejsze w porównaniu z klasycznym podejściem JavaScript.

Ten nowy interfejs API współpracuje też z istniejącym interfejsem Web Animations API (WAAPI) i interfejsem CSS Animations API, aby umożliwić deklaratywne animacje oparte na przewijaniu.

Więcej przykładowych projektów i zasobów

Różne implementacje animacji opartych na przewijaniu możesz sprawdzić w tej witrynie demonstracyjnej, gdzie możesz porównać przykładowe projekty korzystające z tych nowych interfejsów API w CSS i JavaScript.

Jeśli chcesz dowiedzieć się więcej o nowych animacjach opartych na przewijaniu, przeczytaj ten artykuł i obejrzyj prezentację z I/O 2023.