Tamanho de DOM grande tem mais efeito na interatividade do que você imagina. Neste guia, explicamos o motivo e o que você pode fazer.
Não tem jeito: quando você cria uma página da Web, ela tem um Modelo de Objeto de Documento (DOM). O DOM representa a estrutura do HTML da página e concede acesso a JavaScript e CSS à estrutura e ao conteúdo da página.
No entanto, o problema é que o tamanho do DOM afeta a capacidade do navegador de renderizar uma página de maneira rápida e eficiente. De modo geral, quanto maior for o DOM, mais caro será para renderizar inicialmente essa página e atualizar a renderização mais tarde no ciclo de vida da página.
Isso se torna problemático em páginas com DOMs muito grandes quando as interações que modificam ou atualizam o DOM acionam um trabalho de layout caro que afeta a capacidade da página de responder rapidamente. O trabalho de layout caro pode afetar a Interação com a próxima pintura (INP) de uma página. Se você quiser que uma página responda rapidamente às interações do usuário, é importante garantir que os tamanhos do DOM sejam apenas os necessários.
Quando o DOM de uma página é muito grande?
De acordo com o Lighthouse, o tamanho do DOM de uma página é excessivo quando excede 1.400 nós. O Lighthouse começará a emitir avisos quando o DOM de uma página exceder 800 nós. Confira o exemplo de HTML abaixo:
<ul>
<li>List item one.</li>
<li>List item two.</li>
<li>List item three.</li>
</ul>
No código acima, há quatro elementos DOM: o elemento <ul>
e os três elementos filhos <li>
. Sua página da Web provavelmente terá muitos mais nós do que este. Portanto, é importante entender o que você pode fazer para manter os tamanhos do DOM sob controle, bem como outras estratégias para otimizar o trabalho de renderização depois de deixar o DOM de uma página o menor possível.
Como os DOMs grandes afetam a performance da página?
DOMs grandes afetam o desempenho da página de algumas maneiras:
- Durante a renderização inicial da página. Quando o CSS é aplicado a uma página, uma estrutura semelhante ao DOM, conhecida como CSS Object Model (CSSOM), é criada. À medida que os seletores de CSS aumentam em especificidade, o CSSOM se torna mais complexo e é necessário mais tempo para executar o layout, estilo, composição e trabalho de pintura necessários para desenhar a página da Web na tela. Esse trabalho extra aumenta a latência de interações que ocorrem no início do carregamento da página.
- Quando as interações modificam o DOM, seja pela inserção ou exclusão de elementos, seja pela modificação de conteúdos e estilos do DOM, o trabalho necessário para renderizar essa atualização pode resultar em alto custo de layout, estilo, composição e pintura. Assim como no caso da renderização inicial da página, um aumento na especificidade do seletor de CSS pode aumentar o trabalho de renderização quando os elementos HTML são inseridos no DOM como resultado de uma interação.
- Quando o JavaScript consulta o DOM, as referências aos elementos do DOM são armazenadas na memória. Por exemplo, se você chamar
document.querySelectorAll
para selecionar todos os elementos<div>
em uma página, o custo de memória poderá ser considerável se o resultado retornar um grande número de elementos DOM.
Todos esses fatores podem afetar a interatividade, mas o segundo item na lista acima é de especial importância. Se uma interação resultar em uma alteração no DOM, ela poderá iniciar um grande trabalho que pode contribuir para um INP insatisfatório em uma página.
Como medir o tamanho do DOM?
É possível medir o tamanho do DOM de algumas maneiras. O primeiro método usa o Lighthouse. Quando você executa uma auditoria, as estatísticas sobre o DOM da página atual ficam na auditoria "Evite um tamanho excessivo de DOM", no cabeçalho "Diagnóstico". Nesta seção, você pode ver o número total de elementos DOM, o elemento DOM que contém mais elementos filhos, bem como o elemento DOM mais profundo.
Um método mais simples envolve usar o console JavaScript nas ferramentas para desenvolvedores de qualquer navegador importante. Para obter o número total de elementos HTML no DOM, use o seguinte código no console após o carregamento da página:
document.querySelectorAll('*').length;
Se você quiser conferir a atualização do tamanho do DOM em tempo real, também poderá usar a ferramenta de monitoramento de desempenho. Com essa ferramenta, você pode correlacionar operações de layout e estilo (e outros aspectos de desempenho) com o tamanho atual do DOM.
Se o tamanho do DOM se aproximar do limite de aviso do DOM do Lighthouse ou se ele falhar completamente, a próxima etapa será descobrir como reduzir o tamanho do DOM para melhorar a capacidade da página de responder às interações do usuário e melhorar o INP do site.
Como posso medir o número de elementos DOM afetados por uma interação?
Se você estiver criando um perfil de interação lenta no laboratório e suspeitar que ela esteja relacionada ao tamanho do DOM da página, poderá descobrir quantos elementos DOM foram afetados selecionando qualquer parte da atividade no criador de perfil chamada "Recalcular estilo" e observe os dados contextuais no painel inferior.
Na captura de tela acima, observe que o recálculo do estilo do trabalho, quando selecionado, mostra o número de elementos afetados. Embora a captura de tela acima mostre um caso extremo do efeito do tamanho do DOM na renderização de trabalho em uma página com muitos elementos do DOM, essas informações de diagnóstico são úteis em qualquer caso para determinar se o tamanho do DOM é um fator limitante no tempo que leva para o próximo frame ser renderizado em resposta a uma interação.
Como posso reduzir o tamanho do DOM?
Além de auditar o HTML de seu site para marcação desnecessária, a principal forma de reduzir o tamanho do DOM é reduzir a profundidade dele. Se você estiver vendo uma marcação com esta aparência na guia Elementos das ferramentas para desenvolvedores do seu navegador, um sinal de que seu DOM pode ser profundo desnecessariamente é algo como:
<div>
<div>
<div>
<div>
<!-- Contents -->
</div>
</div>
</div>
</div>
Quando você encontrar padrões como esse, provavelmente poderá simplificá-los simplificando a estrutura do DOM. Isso reduz o número de elementos DOM e provavelmente oferece a oportunidade de simplificar os estilos da página.
A profundidade do DOM também pode ser um sintoma das estruturas usadas. Especificamente, frameworks baseados em componentes, como aqueles que dependem do JSX, exigem que você aninhe vários componentes em um contêiner pai.
No entanto, muitos frameworks permitem evitar o aninhamento de componentes usando o que são conhecidos como fragmentos. Os frameworks baseados em componentes que oferecem fragmentos como um recurso incluem (entre outros):
Ao usar fragmentos no framework de sua escolha, você pode reduzir a profundidade do DOM. Se você está preocupado com o impacto do achatamento da estrutura DOM no estilo, use modos de layout mais modernos (e mais rápidos), como flexbox ou grid.
Outras estratégias a considerar
Mesmo que você se esforce para achatar a árvore DOM e remover elementos HTML desnecessários para manter o DOM o menor possível, ele ainda pode ser muito grande e iniciar muito trabalho de renderização à medida que muda em resposta às interações do usuário. Se você estiver nessa situação, há outras estratégias que podem ser consideradas para limitar o trabalho de renderização.
Considere uma abordagem aditiva
Talvez você esteja em uma posição em que grandes partes da página não são visíveis para o usuário quando ela é renderizada pela primeira vez. Essa pode ser uma oportunidade para carregar o HTML com atraso omitindo essas partes do DOM na inicialização, mas adicionando-as quando o usuário interage com as partes da página que exigem os aspectos inicialmente ocultos da página.
Essa abordagem é útil durante o carregamento inicial e talvez até depois. Para o carregamento da página inicial, você assumirá menos trabalho de renderização antecipadamente, o que significa que sua carga HTML inicial será mais leve e mais rápida. Isso vai dar às interações durante esse período crucial mais oportunidades de execução com menos competição pela atenção da linha de execução principal.
Se muitas partes da página estiverem inicialmente ocultas no carregamento, isso também poderá acelerar outras interações que acionam o trabalho de renderização. No entanto, à medida que outras interações acrescentam mais elementos ao DOM, o trabalho de renderização aumenta à medida que o DOM cresce ao longo do ciclo de vida da página.
Adicionar ao DOM ao longo do tempo pode ser complicado e tem suas próprias compensações. Se seguir esse caminho, você provavelmente estará fazendo solicitações de rede para obter dados a fim de preencher o HTML que pretende adicionar à página em resposta a uma interação do usuário. Embora as solicitações de rede em trânsito não sejam contabilizadas para o INP, isso pode aumentar a latência percebida. Se possível, mostre um ícone de carregamento ou outro indicador de que os dados estão sendo buscados para que os usuários entendam que algo está acontecendo.
Limitar a complexidade do seletor de CSS
Quando o navegador analisa os seletores no CSS, ele precisa percorrer a árvore DOM para entender como e se esses seletores se aplicam ao layout atual. Quanto mais complexos esses seletores forem, mais trabalho o navegador terá para realizar a renderização inicial da página, além de aumentar os recalculos de estilo e o trabalho de layout se a página mudar como resultado de uma interação.
Usar a propriedade content-visibility
O CSS oferece a propriedade content-visibility
, que é uma maneira de renderizar de forma lenta os elementos DOM fora da tela. À medida que os elementos se aproximam da viewport, eles são renderizados sob demanda. Os benefícios do content-visibility
não apenas reduzem uma quantidade significativa de trabalho de renderização na renderização inicial da página, mas também pulam o trabalho de renderização de elementos fora da tela quando o DOM da página é modificado como resultado de uma interação do usuário.
Conclusão
Reduzir o tamanho do DOM apenas ao que é estritamente necessário é uma boa maneira de otimizar o INP do seu site. Ao fazer isso, você pode reduzir o tempo que o navegador leva para executar o layout e a renderização quando o DOM é atualizado. Mesmo que não seja possível reduzir significativamente o tamanho do DOM, existem algumas técnicas que podem ser usadas para isolar o trabalho de renderização em uma subárvore do DOM, como a contenção de CSS e a propriedade CSS content-visibility
.
Independentemente do método, criando um ambiente em que o trabalho de renderização seja minimizado, bem como reduzindo o trabalho de renderização que a página realiza em resposta às interações, o resultado será um site mais responsivo aos usuários. Isso significa que o INP do seu site será menor, o que resulta em uma melhor experiência do usuário.