Por que algumas animações estão lentas?

Os navegadores mais recentes podem animar duas propriedades CSS de maneira econômica: transform e opacity. Se você animar qualquer outra coisa, provavelmente não alcançará 60 quadros por segundo (QPS) suaves. Esta postagem explica o motivo.

Desempenho da animação e frame rate

É amplamente aceito que uma taxa de 60 QPS é o alvo ao animar qualquer coisa na Web. Esse frame rate garante que as animações tenham uma aparência suave. Na Web, um frame é o tempo que leva para fazer todo o trabalho necessário para atualizar e repintar a tela. Se cada frame não for concluído em 16,7 ms (1000 ms / 60 ≈ 16,7), os usuários vão perceber o atraso.

Pipeline de renderização

Para mostrar algo em uma página da Web, o navegador precisa seguir estas etapas sequenciais:

  1. Estilo: calcule os estilos que se aplicam aos elementos.
  2. Layout: gere a geometria e a posição de cada elemento.
  3. Paint: preencha os pixels de cada elemento em camadas.
  4. Composto: desenha as camadas na tela.

Essas quatro etapas são conhecidas como o pipeline de renderização do navegador.

Quando você anima algo em uma página que já foi carregada, essas etapas precisam acontecer novamente. Esse processo começa na etapa que precisa ser alterada para permitir que a animação ocorra.

Como mencionado anteriormente, essas etapas são sequenciais. Por exemplo, se você animar algo que muda o layout, as etapas de pintura e composição também precisam ser executadas novamente. Animar algo que muda o layout é mais caro do que animar algo que só muda a composição.

Animar propriedades de layout

As mudanças de layout envolvem o cálculo da geometria (posição e tamanho) de todos os elementos afetados pela mudança. Se você mudar um elemento, a geometria de outros elementos poderá precisar ser recalculada. Por exemplo, se você mudar a largura do elemento <html>, qualquer um dos filhos dele poderá ser afetado. Devido à forma como os elementos estouram e afetam uns aos outros, as mudanças mais abaixo na árvore às vezes podem resultar em cálculos de layout até o topo.

Quanto maior a árvore de elementos visíveis, mais tempo leva para realizar cálculos de layout.

Como animar propriedades de pintura

Pintar é o processo de determinar em que ordem os elementos precisam ser pintados na tela. Muitas vezes, é a tarefa mais longa do pipeline.

A maioria da pintura em navegadores modernos é feita em rasterizadores de software. Dependendo de como os elementos no app são agrupados em camadas, outros elementos além do que mudou também podem precisar ser pintados.

Como animar propriedades compostas

A composição é o processo de separar a página em camadas, converter as informações sobre como a página deve ficar em pixels (rasterização) e juntar as camadas para criar uma página (composição).

É por isso que a propriedade opacity está incluída na lista de coisas que são baratas de animar. Contanto que essa propriedade esteja na própria camada, as alterações podem ser processadas pela GPU durante a etapa de composição. Os navegadores baseados no Chromium e o WebKit criam uma nova camada para qualquer elemento que tenha uma transição ou animação CSS em opacity.

O que é uma camada?

Ao colocar os elementos que serão animados ou transferidos para uma nova camada, o navegador só precisa pintar esses itens, e não tudo. Você pode conhecer o conceito do Photoshop de uma camada que contém vários elementos que podem ser movidos juntos. As camadas de renderização do navegador são semelhantes a essa ideia.

Embora o navegador faça um bom trabalho ao tomar decisões sobre quais elementos devem estar em uma nova camada, se ele perder um, há maneiras de forçar a criação de camadas. Saiba mais em Como criar animações de alto desempenho. No entanto, a criação de novas camadas deve ser feita com cuidado, porque cada camada usa memória. Em dispositivos com memória limitada, a criação de novas camadas pode causar mais problemas de desempenho do que o que você está tentando resolver. Além disso, as texturas de cada camada precisam ser enviadas para a GPU. Portanto, você pode encontrar restrições de largura de banda entre a CPU e a GPU.

Desempenho do CSS vs JavaScript

Você pode se perguntar: é melhor usar CSS ou JavaScript para animações do ponto de vista de desempenho?

Animações baseadas em CSS e animações da Web (nos navegadores que oferecem suporte à API) geralmente são gerenciadas em um encadeamento conhecido como encadeamento de composição. Isso é diferente da linha de execução principal do navegador, em que o estilo, o layout, a pintura e o JavaScript são executados. Isso significa que, se o navegador estiver executando algumas tarefas caras no encadeamento principal, essas animações podem continuar sem interrupções.

Conforme explicado neste artigo, outras mudanças em transformações e opacidade podem, em muitos casos, também ser processadas pela linha de execução do compositor.

Se alguma animação acionar uma pintura, um layout ou ambos, a linha de execução principal precisará funcionar. Isso vale para animações CSS e JavaScript, e a sobrecarga do layout ou pintura provavelmente minimizará qualquer trabalho associado à execução do CSS ou JavaScript, tornando a questão discutível.