O JavaScript geralmente é um gatilho para mudanças visuais. Às vezes, ele faz essas mudanças diretamente por manipulações de estilo e, às vezes, por cálculos que resultam em mudanças visuais, como pesquisa ou classificação de dados. O JavaScript mal programado ou de longa duração pode ser uma causa comum de problemas de performance, e você precisa minimizar o impacto dele sempre que possível.
Cálculo de estilo
A mudança do DOM pela adição e remoção de elementos, alteração de atributos, classes ou reprodução de animações faz com que o navegador recalcule os estilos dos elementos e, em muitos casos, o layout de parte ou de toda a página. Esse processo é chamado de cálculo de estilo.
O navegador começa a calcular os estilos criando um conjunto de seletores correspondentes para determinar quais classes, pseudoseletores e IDs se aplicam a um determinado elemento. Em seguida, ele processa as regras de estilo dos seletores correspondentes e descobre quais estilos finais o elemento tem.
(link em inglês)O papel do recálculo de estilo na latência de interação
Interaction to Next Paint (INP) é uma métrica de performance de tempo de execução centrada no usuário que avalia a capacidade de resposta geral de uma página à entrada do usuário. Ela mede a latência de interação desde o momento em que o usuário interage com a página até o navegador renderizar o próximo frame mostrando as atualizações visuais correspondentes na interface do usuário.
Um componente significativo de uma interação é o tempo necessário para renderizar o próximo frame. O trabalho de renderização feito para apresentar o próximo frame é composto de muitas partes, incluindo o cálculo dos estilos da página que ocorrem pouco antes do layout, da renderização e do trabalho de composição. Este guia se concentra nos custos de cálculo de estilo, mas reduzir qualquer parte da duração total da renderização da interação também reduz a latência total.
Reduza a complexidade dos seletores
Simplificar os seletores de CSS pode ajudar a acelerar os cálculos de estilo da página. Os seletores mais simples referenciam um elemento em CSS com apenas um nome de classe:
.title {
/* styles */
}
No entanto, à medida que um projeto cresce, ele provavelmente precisa de CSS mais complexo, e você pode acabar com seletores como este:
.box:nth-last-child(-n+1) .title {
/* styles */
}
Para determinar como esses estilos se aplicam à página, o navegador precisa perguntar: "este é um elemento com uma classe de title com um pai de uma classe de box que é o filho menos-n-ésimo-mais-1 do elemento pai? Descobrir isso pode levar algum tempo para o navegador. Para simplificar, você pode mudar o seletor para um nome de classe mais específico:
.final-box-title {
/* styles */
}
Esses nomes de classe de substituição podem parecer estranhos, mas simplificam muito o trabalho do navegador. Na versão anterior, por exemplo, para que o navegador saiba que um elemento é o último do tipo, ele precisa primeiro saber tudo sobre todos os outros elementos para determinar se há elementos que vêm depois dele que podem ser o nth-last-child. Isso pode ser muito mais caro do ponto de vista computacional do que corresponder um seletor a um elemento com base apenas no nome da classe.
Reduza o número de elementos com estilo
Outra consideração de performance, e geralmente mais importante do que a complexidade do seletor, é a quantidade de trabalho que precisa acontecer quando um elemento muda.
Em termos gerais, o pior custo de cálculo do estilo de elementos computados é o número de elementos multiplicado pela contagem de seletores, porque o navegador precisa verificar cada elemento pelo menos uma vez em relação a cada estilo para ver se ele corresponde.
Os cálculos de estilo podem segmentar alguns elementos diretamente em vez de invalidar toda a página. Em navegadores modernos, isso tende a ser menos problemático porque o navegador nem sempre precisa verificar todos os elementos que uma mudança pode afetar. Por outro lado, navegadores mais antigos nem sempre são otimizados para essas tarefas. Sempre que possível, reduza o número de elementos invalidados.
Meça o custo do recálculo de estilo
Há algumas maneiras de medir o custo do recálculo de estilo no navegador. Cada uma delas depende de você querer medir no navegador no ambiente de desenvolvimento ou se quer medir quanto tempo esse processo leva para usuários reais no seu site.
Medir o custo do recálculo de estilo no Chrome DevTools
Uma maneira de medir o custo dos recálculos de estilo é usar o painel de performance no Chrome DevTools. Faça o seguinte para começar:
- Abra o DevTools.
- Navegue até a guia Performance.
- Marque a caixa de seleção Estatísticas do seletor (opcional).
- Clique em Gravar.
- Interaja com a página.
Quando você parar de gravar, verá algo como a imagem a seguir:
A faixa na parte de cima é um gráfico de chamas em miniatura que também representa frames por segundo. Quanto mais próxima a atividade estiver da parte de baixo da faixa, mais rápido os frames serão renderizados pelo navegador. Se você vir o gráfico de chamas nivelando na parte de cima com barras vermelhas acima dele, isso significa que você tem um trabalho que está causando frames de longa duração.
Frames de longa duração durante uma interação, como a rolagem, merecem uma análise mais detalhada. Se você vir um grande bloco roxo, aumente o zoom na atividade e selecione qualquer trabalho rotulado como Recalcular estilo para mais informações sobre o trabalho de recálculo de estilo potencialmente caro.
Clicar no evento mostra a pilha de chamadas dele. Se o trabalho de renderização foi causado por uma interação do usuário, ele chama o JavaScript que acionou a mudança de estilo. Ele também mostra o número de elementos afetados pela mudança (pouco mais de 900 elementos nesse caso) e quanto tempo o cálculo de estilo levou. Você pode usar essas informações para começar a encontrar uma correção no seu código.
Se você marcou a caixa de seleção Estatísticas do seletor nas configurações do Painel de performance antes de fazer um rastreamento, o painel de baixo no rastreamento terá outra guia com o mesmo nome.
Esse painel fornece dados úteis sobre o custo relativo de cada seletor, permitindo que você identifique seletores de CSS caros.
Para mais informações, consulte a documentação de estatísticas do seletor de CSS.
Medir o custo do recálculo de estilo para usuários reais
Se você quiser saber quanto tempo leva para o recálculo de estilo ocorrer para
usuários reais do seu site, a API Long Animation Frames
oferece as ferramentas necessárias para isso. Os dados dessa API foram adicionados a a
web-vitals biblioteca JavaScript,
incluindo o tempo de recálculo de estilo.
Se você suspeitar que o atraso na apresentação de uma interação é o principal fator que contribui para o INP de uma página, descubra quanto tempo é gasto no recálculo de estilos na página. Para mais informações, leia sobre como medir o tempo de recálculo de estilo no campo.