Devs & IA

O que trava a interface: as três etapas que o navegador refaz

Anderson Ventura5 min de leitura

"O site está travando no celular" é um dos relatos mais frustrantes que existem, porque parece problema de máquina fraca e quase nunca é. Na maioria dos casos que investiguei, a causa era específica e barata de corrigir: alguma coisa animando a propriedade errada.

Para consertar sem chutar, ajuda entender o que o navegador faz sessenta vezes por segundo.

As três etapas

Para cada quadro, o navegador pode precisar refazer até três coisas:

  1. Layout — calcular posição e tamanho de cada elemento. É a etapa mais cara, porque mexer num elemento pode obrigar a recalcular os vizinhos, e às vezes a página inteira.
  2. Paint — pintar os pixels: cores, bordas, sombras, texto.
  3. Composite — juntar as camadas já pintadas na tela. É a mais barata e pode acontecer fora da linha principal.

O ponto que muda tudo: a propriedade que você anima determina em qual etapa o trabalho começa. E o trabalho vem em cascata — mexer no layout obriga a repintar e recompor também.

O mapa de custo

PropriedadeRefazCusto
transform, opacitycompositeBarato
background-color, box-shadow, filterpaint + compositeMédio
width, height, top, left, margin, paddinglayout + paint + compositeCaro

Na prática isso vira uma regra curta: para mover, use translate em vez de top ou left. Para redimensionar, use scale em vez de width e height. O efeito visual é o mesmo; o custo não é.

Veja um elemento se movendo com transform — a versão barata:

E um que anima altura, mexendo no layout a cada quadro:

Nas duas, isolado, você não vê diferença. É esse o problema — o custo só aparece quando multiplica.

Por que "funciona na minha máquina"

Seu computador de trabalho tem folga de sobra. Ele absorve trabalho desperdiçado sem reclamar, e você entrega achando que está tudo bem.

O celular de quem usa o produto tem processador mais fraco, memória menor e às vezes está com bateria em modo de economia — que reduz a frequência do processador de propósito. É lá que os mesmos sessenta quadros por segundo viram vinte.

Uma animação cara não trava nada. Quarenta na mesma tela travam — e sempre no aparelho de quem você menos queria decepcionar.

O multiplicador é quase sempre lista. Um card com sombra animada no hover é irrelevante. Uma grade com quarenta cards, cada um com sombra animada, é outra história — e é exatamente o padrão que aparece em catálogo, marketplace e painel.

Os quatro padrões que mais aparecem

1. Sombra animada em lista

box-shadow força repintura de uma área maior que o próprio elemento, porque a sombra vaza para fora. Em lista longa, é o campeão de travamento.

Saída: deixe a sombra fixa e anime transform: translateY() — a sensação de elevação vem do deslocamento. Ou coloque a sombra num pseudo-elemento e anime só a opacidade dele.

2. Animar left e top

Herança de tutorial antigo. Toda vez que o valor muda, o navegador recalcula a posição — e, dependendo do contexto, a dos vizinhos também.

Saída: transform: translate(). Aceita as mesmas unidades e resolve na etapa final.

3. filter em elemento grande

Desfoque é caro por natureza: o navegador precisa ler os pixels ao redor de cada ponto. Num elemento pequeno, tudo bem. Numa área grande, ou com vários ao mesmo tempo, o custo dispara.

A peça abaixo usa desfoque na entrada. Vale no destaque principal da página — não em lista:

4. Animar cor de fundo em muitos elementos

Mais barato que layout, mas ainda é repintura. Em uma tabela com centenas de linhas que mudam de cor ao passar o mouse, aparece.

Saída: quando possível, sobreponha uma camada com opacidade animada em vez de trocar a cor.

Como medir em vez de adivinhar

Palpite sobre performance costuma estar errado. Duas checagens rápidas:

  1. Grave um perfil nas ferramentas de desenvolvedor enquanto reproduz o travamento. Barras longas na linha do tempo mostram onde o tempo vai — e se aparece "layout" ou "recalculate style" repetidamente durante uma animação, achou o culpado.
  2. Reduza a velocidade do processador nas próprias ferramentas. É a forma mais honesta de sentir o que o público sente, sem precisar de um aparelho antigo na mesa.

Faça isso antes de otimizar. Já vi bastante tempo gasto deixando animação mais eficiente quando o gargalo real era uma imagem enorme carregando junto.

Duas ferramentas que ajudam — e uma que atrapalha

will-change avisa o navegador que uma propriedade vai mudar, e ele prepara uma camada separada. Usado com moderação, resolve engasgo no início da animação. Usado em tudo, consome memória e piora — cada camada tem custo. Aplique no elemento específico, pouco antes de animar.

content-visibility permite pular a renderização do que está fora da tela. Em página longa, o ganho é grande.

E a que atrapalha: transform: translateZ(0) como truque genérico. Era o jeito antigo de forçar aceleração. Hoje o navegador decide melhor sozinho, e espalhar isso pelo código cria dezenas de camadas desnecessárias — que é justamente o problema que você queria evitar.

O caso em que animar caro é o certo

Nada disso significa proibição. Um painel que expande precisa empurrar o conteúdo de baixo — é isso que a interface está comunicando. Fazer com transform deixaria os elementos sobrepostos.

A diferença é intenção: animar layout porque o layout é o ponto, uma vez na tela, com duração curta. Não por hábito, em quarenta elementos, porque foi o primeiro jeito que funcionou.

O resumo em quatro linhas

  • Para mover: translate. Para crescer: scale.
  • Sombra e desfoque: fixos, ou animados uma vez só na tela.
  • Desconfie sempre que a animação estiver dentro de lista.
  • Meça com o processador reduzido antes de decidir que está bom.

São quatro decisões que não custam tempo nenhum se tomadas enquanto você escreve — e custam bastante quando viram relato de "o site trava no celular" três meses depois.

As peças usadas aqui estão no acervo de animações, com o comentário de custo no próprio código de cada uma.

CompartilharXLinkedInWhatsApp

Continue lendo