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

Os navegadores modernos podem animar duas propriedades CSS de forma econômica: transform e opacity. Se você animar qualquer outra coisa, provavelmente não vai atingir 60 QPS. 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. Essa taxa de frames garante que as animações fiquem suaves. 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: calcula os estilos aplicados aos elementos.
  2. Layout: gere a geometria e a posição de cada elemento.
  3. Pintura: preencha os pixels de cada elemento.
  4. Composto: separe os elementos em camadas e desenhe 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 aconteça.

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.

Como 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 transbordam e afetam uns aos outros, as mudanças mais abaixo na árvore às vezes podem resultar em cálculos de layout de volta ao topo.

Quanto maior a árvore de elementos visíveis, mais tempo leva para realizar os 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 demorada do pipeline.

A maioria da pintura em navegadores modernos é feita em rasterizadores de software. Dependendo de como os elementos do 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, convertendo as informações sobre como a página deve ficar em pixels (rasterização) e juntando 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. Enquanto essa propriedade estiver na própria camada, as mudanças nela poderão 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 precisam 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 precisa 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?

As animações baseadas em CSS e as animações da Web (nos navegadores que oferecem suporte à API) são normalmente processadas em uma linha de execução conhecida como linha de execução do compositor. 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 na linha de execução principal, essas animações poderão continuar sem serem interrompidas.

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

Se alguma animação acionar a pintura, o layout ou ambos, a linha de execução principal será necessária para fazer o trabalho. Isso é válido para animações CSS e JavaScript, e a sobrecarga de layout ou pintura provavelmente vai ofuscar qualquer trabalho associado à execução de CSS ou JavaScript, tornando a pergunta irrelevante.