Adiar a renderização de conteúdo pesado

Recursos da Web: content-visibility

Páginas da Web com conteúdo extenso, como rolagem infinita, painéis complexos ou artigos densos, podem sofrer com renderização inicial lenta e interações lentas. As tecnologias modernas da Web permitem adiar a carga de trabalho de renderização de conteúdo que não está visível imediatamente, o que melhora significativamente o desempenho sem prejudicar a acessibilidade ou as expectativas do usuário.

Para otimizar a renderização, use a propriedade CSS content-visibility e o atributo HTML hidden="until-found". Embora ambos ajudem no desempenho, eles atendem a casos de uso distintos.

Quando usar qual

Cenário/exemplo Recurso aplicado Benefícios na performance
1. Abaixo da dobra (atrasar o carregamento inicial) content-visibility: auto O navegador descarrega automaticamente a carga de trabalho de layout/pintura até que o contêiner role para perto da visualização, mantendo a velocidade de carregamento de página padrão sem atrito.
2. Alternar estado (alternância rápida de visualização) content-visibility: hidden Ignora os cálculos de layout para divs ocultas, mas preserva o estado de contenção de estilo, permitindo a alternância instantânea sem mudanças estruturais (superior a display: none).
3. Pesquisável e adiado (declarações recolhíveis) hidden="until-found" Para instruções detalhadas sobre como combinar a performance de renderização com a acessibilidade da pesquisa na página, consulte Pesquisar conteúdo oculto.

Como implementar o content-visibility: auto

Escolher conteúdo fora da tela

OBRIGATÓRIO: você PRECISA identificar com cuidado quais elementos recebem content-visibility: auto.

  • FAÇA a segmentação de blocos de layout grandes e independentes que estão estritamente abaixo da dobra inicial (por exemplo, itens de card em um feed infinito, comentários finais ou seções de layout com muito conteúdo na parte de baixo).
  • NÃO aplique essa propriedade a elementos na janela de visualização inicial, acima da dobra. Isso força o navegador a avaliar os limites de visibilidade antes da renderização, o que, paradoxalmente, atrasa o desempenho crítico de carregamento de página.
  • FAÇA a segmentação de elementos com estruturas DOM internas profundas ou complexas para maximizar a economia de custos de renderização.

Etapas de implementação

  1. OBRIGATÓRIO: identifique seções pesadas que estão fora da tela no carregamento inicial.
  2. OBRIGATÓRIO: aplique content-visibility: auto a cada um desses elementos fora da tela.
  3. OBRIGATÓRIO: forneça um tamanho estimado da estrutura de layout usando contain-intrinsic-size em cada elemento.

Como usar contain-intrinsic-size

OBRIGATÓRIO: você PRECISA parear content-visibility: auto com contain-intrinsic-size. Se isso não for feito, o navegador vai reduzir o elemento para uma altura de 0 px quando ele estiver fora da tela, causando mudanças graves de layout e saltos na barra de rolagem conforme o usuário rola a página.

A propriedade abreviada de CSS contain-intrinsic-size funciona como uma dimensão de marcador de posição. O uso da palavra-chave auto permite que o navegador "lembre" o tamanho exato quando o elemento é renderizado, usando esse tamanho calculado em vez do marcador de posição se o elemento sair da tela novamente.

Exemplo de código

/* DO ONLY apply this class to items OUTSIDE the initial layout viewport */
.heavy-section-deferred {
  /* MANDATORY: Skips rendering calculations when off-screen */
  content-visibility: auto;
  
  /* Mandatory: Provide an estimated size to prevent layouts shifts.
    - 'auto' is optional and enables the browser to remember the actual size
      once rendered. It must be paired with a <length> value to be used for
      the first render.
    - 'none' tells the browser not to apply any intrinsic width to this element.
      It can be used for either the height or the width value.
    - '150px' is the estimated height of this element. This can be any valid
      CSS <length> value.
   */
  contain-intrinsic-size: auto none auto 150px; 
}

Como implementar o content-visibility: hidden

  1. Identifique seções pesadas: localize blocos de layout que estão inicialmente ocultos (por exemplo, linhas extras em uma tabela de dados grande).
  2. Aplicar CSS: adicione content-visibility: hidden ao elemento.
  3. Revelar o elemento: quando o elemento precisar ser revelado, mude a propriedade content-visibility para visible ou auto.

Exemplo de código

.cached-view {
  /* Hides content but caches rendering state */
  content-visibility: hidden;
}

.cached-view.is-active {
  content-visibility: visible;
}

Como content-visibility: hidden exclui o elemento e os filhos dele da árvore de acessibilidade e da pesquisa na página, NÃO use esse atributo se o conteúdo precisar permanecer detectável enquanto estiver oculto. Se você precisar que o conteúdo oculto permaneça pesquisável usando o recurso nativo de localização na página, use hidden="until-found" conforme descrito em Pesquisar conteúdo oculto.

Práticas recomendadas

  • RECOMENDAÇÃO: use contain-intrinsic-size com content-visibility: auto. Se isso não for feito, a altura será recalculada durante a rolagem, o que pode causar saltos no layout da janela de visualização ou falhas visuais.
  • NÃO aplique content-visibility: auto a elementos dentro da janela de visualização inicial, porque isso atrasa a renderização de páginas críticas.
  • Verificação de acessibilidade OBRIGATÓRIA: ao aplicar content-visibility: auto, você PRECISA verificar a acessibilidade sequencial do teclado. Em algumas configurações de tecnologia adaptativa, os nós fora da tela que usam content-visibility: auto podem ser excluídos da árvore de acessibilidade ou das rotas de navegação sequencial até que o foco seja movido para dentro deles. Teste a navegação linear além dos limites da tela usando apenas o teclado.

Estratégias de fallback

content-visibility de substituição

Quando content-visibility não é compatível, ele é ignorado pelo navegador. Na maioria dos casos, content-visibility: auto não precisa de um substituto, mas sem ele os ganhos de desempenho serão perdidos. Um navegador incompatível vai deixar os elementos content-visibility: hidden completamente visíveis. Use a detecção de recursos para implementar um substituto.

/* Default for everyone */
.inactive {
  display: none;
}

/* Modern Browsers only */
@supports (content-visibility: hidden) {
 .inactive {
    display: block; /* Turn the layout box back on */
    content-visibility: hidden;
  }
}