Um estudo de caso sobre o desempenho de animações de rolagem

Yuriko Hirota
Yuriko Hirota

O que há de novo nas animações de rolagem?

As animações de rolagem são uma maneira de adicionar interatividade e interesse visual ao seu site ou aplicativo da Web, acionadas pela posição de rolagem do usuário. Essa pode ser uma ótima maneira de manter os usuários engajados e tornar seu site mais atraente visualmente.

No passado, a única maneira de criar animações de rolagem era responder ao evento de rolagem na linha de execução principal. Isso causou dois grandes problemas:

  • A rolagem é realizada em uma linha de execução separada e, portanto, fornece eventos de rolagem de forma assíncrona.
  • As animações da linha de execução principal estão sujeitas a instabilidade.

Isso torna impossível ou muito difícil criar animações de rolagem de alto desempenho sincronizadas com a rolagem.

Estamos lançando um novo conjunto de APIs para oferecer suporte a animações de rolagem, que podem ser usadas em CSS ou JavaScript. A API tenta usar o mínimo possível de recursos de linha de execução principais, tornando as animações de rolagem muito mais fáceis de implementar e muito mais suaves. No momento, a API de animações de rolagem é compatível com os seguintes navegadores:

Compatibilidade com navegadores

  • 115
  • 115
  • x

Origem

Este artigo compara a nova abordagem com a técnica clássica do JavaScript para mostrar como podem ser fáceis e suaves animações de rolagem com a nova API.

API CSS de animações de rolagem em comparação com JavaScript clássico

O exemplo de barra de progresso a seguir foi criado usando técnicas de classe JavaScript.

O documento responde sempre que o evento scroll calcula a porcentagem da scrollHeight que o usuário rolou.

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

A demonstração a seguir mostra a mesma barra de progresso usando a nova API com CSS.

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

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

O novo recurso CSS animation-timeline converte automaticamente uma posição de um intervalo de rolagem em uma porcentagem de progresso, fazendo todo o trabalho pesado.

Agora, a parte interessante: digamos que você tenha implementado um cálculo superpesado nas duas versões do site, o que consumiria a maior parte dos principais recursos da linha de execução.

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

Como esperado, a versão clássica do JavaScript se torna instável e lenta devido à junção de recursos de linha de execução principal. Por outro lado, a versão do CSS não é afetada pelo trabalho pesado de JavaScript e pode responder às interações de rolagem do usuário.

.
.

O uso da CPU é completamente diferente no DevTools, como mostrado nas capturas de tela a seguir.

Comparação da linha de execução principal.

A demonstração a seguir mostra um aplicativo de animação de rolagem criada pelo CyberAgent. Perceba que a foto aparece quando você rola a tela.

.

Nova API JavaScript de animações com rolagem em comparação com o JavaScript clássico

Os benefícios da nova API não se limitam apenas ao CSS. Você também pode criar animações fluidas orientadas por rolagem usando JavaScript. Confira o exemplo a seguir:

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

Dessa forma, é possível criar a mesma animação da barra de progresso mostrada na demonstração anterior do CSS usando apenas JavaScript. A tecnologia subjacente é a mesma da versão CSS. A API tenta usar o mínimo possível de recursos de linha de execução principais, tornando as animações muito mais suaves em comparação com a abordagem JavaScript clássica.

Além disso, a nova API funciona em conjunto com a API Web Animations (WAAPI) e a API CSS Animations (links em inglês) para ativar animações declarativas de rolagem.

.
.

Mais demonstrações e recursos

Confira as diferentes implementações de animação de rolagem neste site de demonstração, onde é possível comparar demonstrações usando essas novas APIs de CSS e JavaScript.

Se você quiser saber mais sobre as novas animações de rolagem, confira este artigo e a palestra do Google I/O 2023 (em inglês).