content-visibilidade: a nova propriedade de CSS que melhora o desempenho de renderização

Melhore o tempo de carregamento inicial ignorando a renderização de conteúdo fora da tela.

A content-visibility lançada no Chromium 85, pode ser um dos novos CSS mais impactantes para melhorar o desempenho do carregamento de página. content-visibility ativa os o user agent de pular o trabalho de renderização de um elemento, incluindo o layout e a pintura, até que sejam necessários. Como a renderização é ignorada, se uma grande parte do conteúdo está fora da tela, usar a propriedade content-visibility torna o o carregamento inicial do usuário muito mais rápido. Isso também permite interações mais rápidas com o conteúdo na tela. Muito legal.

demonstração com figuras que representam resultados da rede
Na demonstração do nosso artigo, aplicar content-visibility: auto a áreas de conteúdo divididas proporciona um aumento de 7x no desempenho de renderização no carregamento inicial. Continue lendo para saber mais.

Suporte ao navegador

Compatibilidade com navegadores

  • 85
  • 85
  • 125
  • 18

Origem

content-visibility depende de primitivos dentro da contenção CSS Especificação. Enquanto content-visibility é de suportado no Chromium 85 por enquanto (e considerado "vale a pena prototipagem" para Firefox), a especificação de contenção tem suporte na maioria navegadores.

Contenção de CSS

O principal objetivo da contenção do CSS é permitir a renderização de melhoria no desempenho do conteúdo da web ao fornecer isolamento previsível de uma subárvore do DOM do resto da página.

Basicamente, um desenvolvedor pode informar ao navegador quais partes da página estão encapsuladas como um conjunto de conteúdo, permitindo que os navegadores analisem o conteúdo sem precisar considerar o estado fora da subárvore. Saber quais partes do conteúdo (subárvores) contêm conteúdo isolado, significa que o navegador pode fazer otimização para a renderização da página.

Existem quatro tipos de CSS contenção, cada um como um valor potencial para a propriedade CSS contain, que pode ser combinada em uma lista de valores separados por espaços:

  • size: o tamanho da contenção em um elemento garante que a caixa dele possa ser dispostos sem precisar examinar os descendentes. Isso significa que podemos pode pular o layout dos descendentes se tudo que precisamos for o tamanho do .
  • layout: contenção de layout significa que os descendentes não afetam o o layout externo de outras caixas na página. Isso nos permite pular dos descendentes se quisermos apenas posicionar outras caixas.
  • style: a contenção de estilo garante que as propriedades que podem ter efeitos mais do que apenas seus descendentes não escapar do elemento (por exemplo, contadores). Isso nos permite pular o cálculo de estilo para os descendentes se todos quer é calcular estilos em outros elementos.
  • paint: a contenção de pintura garante que os descendentes da caixa que a contém não são exibidos fora dos limites. Nada pode visivelmente estourar o elemento, e, se um elemento estiver fora da tela ou não estiver visível, seus descendentes ficam visíveis. Isso nos permite pular a pintura da descendentes se o elemento estiver fora da tela.

Pulando o trabalho de renderização com content-visibility

Pode ser difícil descobrir quais valores de contenção usar, pois o navegador só poderão ser iniciadas quando um conjunto apropriado for especificado. Você pode testar os valores para ver o que funciona melhor ou você pode usar outra propriedade CSS chamada content-visibility para aplicar o a contenção automaticamente. Com o content-visibility, você recebe a maior ganhos de desempenho que o navegador pode oferecer com o mínimo de esforço de sua parte, desenvolvedor.

A propriedade de visibilidade do conteúdo aceita vários valores, mas é auto. que oferece melhorias imediatas de desempenho. Um elemento que tem content-visibility: auto ganha contenção de layout, style e paint. Se o elemento está fora da tela (e não é relevante para o usuário, ou seja, elementos sejam os que têm foco ou seleção em sua subárvore), isso também ganha size contenção (e para pintura e teste de hit o conteúdo dele).

O que isso significa? Em resumo, se o elemento está fora da tela, seus descendentes não renderizado. O navegador determina o tamanho do elemento sem considerar todo o conteúdo dele e para ali. A maior parte da renderização, como o estilo e o layout da subárvore do elemento são ignorados.

À medida que o elemento se aproxima da janela de visualização, o navegador não adiciona mais a size. contenção e começa a pintar e fazer um teste de hit no conteúdo do elemento. Isso permite que o trabalho de renderização seja feito exatamente a tempo de ser visto pelo usuário.

Observação sobre acessibilidade

Um dos recursos do content-visibility: auto é que o conteúdo fora da tela permanece disponível no modelo de objeto do documento e, portanto, na árvore de acessibilidade, ao contrário do visibility: hidden. Isso significa que é possível pesquisar e acessar o conteúdo na página sem aguardar o carregamento nem prejudicar o desempenho da renderização.

O lado inverso disso, no entanto, é que elementos de ponto de referência com recursos de estilo como display: none ou visibility: hidden também aparecerão na árvore de acessibilidade quando estiverem fora da tela, já que o navegador não renderizará esses estilos até que eles entrem na janela de visualização. Para evitar que eles fiquem visíveis na árvore de acessibilidade, possivelmente causando confusão, adicione também aria-hidden="true".

Exemplo: um blog de viagens

Neste exemplo, definimos como referência nosso blog de viagens à direita e aplicamos content-visibility: auto às áreas fragmentadas à esquerda. Os resultados mostram tempos de renderização de 232 ms a 30 ms no carregamento inicial da página.

Um blog de viagens normalmente contém um conjunto de histórias com algumas fotos e algumas um texto descritivo. Veja o que acontece em um navegador comum quando acessa um blog de viagens:

  1. Uma parte da página é baixada a partir da rede, junto com os dados necessários do Google Cloud.
  2. O navegador define e apresenta todo o conteúdo da página, sem considerar se o conteúdo é visível para o usuário.
  3. O navegador volta à etapa 1 até que toda a página e todos os recursos sejam baixado.

Na etapa 2, o navegador processa todo o conteúdo procurando elementos que possam mudaram. Ela atualiza o estilo e o layout de todos os novos elementos, além dos elementos que podem ter mudado como resultado das novas atualizações. Isso está renderizando funcionam. Isso leva tempo.

Uma captura de tela de um blog de viagens.
Um exemplo de um blog de viagens. Consulte Demonstração no Codepen

Agora, considere o que acontece se você colocar content-visibility: auto em cada um dos histórias individuais no blog. O loop geral é o mesmo: o navegador faz o download e renderiza partes da página. No entanto, a diferença está no que ele executa na etapa 2.

Com a visibilidade do conteúdo, ele vai estilizar e definir o layout de todo o conteúdo visíveis para o usuário no momento (eles estão na tela). No entanto, ao processar o história totalmente fora da tela, o navegador ignora o trabalho de renderização e apenas definir o estilo e o layout da própria caixa do elemento.

O carregamento desta página seria como se ela estivesse em tela cheia histórias e caixas vazias para cada uma das histórias fora da tela. Isso tem um bom desempenho melhor, com redução esperada de 50% ou mais do custo de renderização de carregando. No exemplo, notamos um aumento do tempo de renderização de 232 ms para um 30 ms de renderização. Isso é um aumento de 7 vezes no desempenho.

Qual é o trabalho que você precisa fazer para colher esses benefícios? Primeiro, nós dividir o conteúdo em seções:

Uma captura de tela anotada da divisão de conteúdo em seções com uma classe CSS.
Exemplo de divisão de conteúdo em seções com a classe story aplicada para receber content-visibility: auto. Consulte Demonstração no Codepen

Em seguida, aplicamos a seguinte regra de estilo às seções:

.story {
  content-visibility: auto;
  contain-intrinsic-size: 1000px; /* Explained in the next section. */
}

Como especificar o tamanho natural de um elemento com contain-intrinsic-size

Para conhecer os possíveis benefícios do content-visibility, o navegador precisa aplicar contenção de tamanho para garantir que os resultados da renderização do conteúdo não afetam o tamanho do elemento de forma alguma. Isso significa que o elemento serão dispostos como se estivessem vazios. Se o elemento não tiver uma altura especificada em um layout de blocos regular, terá a altura 0.

Isso pode não ser o ideal, já que o tamanho da barra de rolagem mudará, sendo se cada história tiver uma altura diferente de zero.

Felizmente, o CSS oferece outra propriedade, contain-intrinsic-size, que especifica efetivamente o tamanho natural do elemento se o elemento for são afetadas pela contenção de tamanho. Em nosso exemplo, vamos defini-lo como 1000px conforme uma estimativa da altura e largura das seções.

Isso significa que ele será apresentado como se tivesse um único filho de "tamanho intrínseco" as dimensões, garantindo que os divs que não foram dimensionados ainda ocupem espaço. contain-intrinsic-size atua como um tamanho de marcador de posição em vez de conteúdo renderizado.

No Chromium 98 em diante, há um novo auto palavra-chave para contain-intrinsic-size. Quando especificado, o navegador lembrará o tamanho da última renderização, se houver, e use-o em vez do marcador de posição fornecido pelo desenvolvedor tamanho. Por exemplo, se você especificou contain-intrinsic-size: auto 300px, o será iniciado com um tamanho intrínseco de 300px em cada dimensão, mas o conteúdo do elemento for renderizado, ele manterá o tamanho intrínseco renderizado. Qualquer alteração subsequente no tamanho de renderização também será lembrada. Na prática, isso significa que, se você role um elemento com content-visibility: auto aplicado e, em seguida, role de volta fora da tela, ele manterá automaticamente a largura e a altura ideais e não reverterá para o dimensionamento do marcador de posição. Esse recurso é muito útil para rolagem infinita, o que agora pode melhorar automaticamente a estimativa de tamanho ao longo do tempo, à medida que o usuário explora a página.

Ocultando conteúdo com o content-visibility: hidden

E se você quiser manter o conteúdo não renderizado, independentemente de ter ou não está na tela, aproveitando os benefícios do estado de renderização em cache? Insira: content-visibility: hidden:

A propriedade content-visibility: hidden oferece os mesmos benefícios de conteúdo não renderizado e estado de renderização em cache como content-visibility: auto faz fora da tela. No entanto, ao contrário de auto, ele não começa a ser são renderizados na tela.

Isso oferece mais controle, permitindo que você oculte o conteúdo de um elemento e depois reexibi-las rapidamente.

Compare-o com outras formas comuns de ocultar o conteúdo do elemento:

  • display: none: oculta o elemento e destrói o estado de renderização. Isso significa que reexibir o elemento é tão caro quanto renderizar um novo elemento com o mesmo conteúdo.
  • visibility: hidden: oculta o elemento e mantém o estado de renderização. Isso não remove o elemento do documento de fato porque ele (e sua subárvore) ainda ocupa espaço geométrico na página e ainda pode ser clicado. Ela também atualiza o estado de renderização sempre que é necessário, mesmo quando está oculto.

content-visibility: hidden, por outro lado, oculta o elemento enquanto o estado de renderização. Por isso, em caso de alterações que precisem acontecerão, elas só acontecem quando o elemento é mostrado novamente (ou seja, o A propriedade content-visibility: hidden foi removida.

Alguns ótimos casos de uso para content-visibility: hidden são ao implementar controles de rolagem virtuais avançados e medição do layout. Eles também são ótimos para aplicativos de página única (SPAs). As visualizações de aplicativos inativas podem ser deixadas no DOM com content-visibility: hidden foi aplicado para impedir a exibição, mas manter a em cache. Isso acelera a renderização da visualização quando ela fica ativa novamente.

Efeitos na interação com a próxima exibição (INP, na sigla em inglês)

INP é uma métrica que avalia a capacidade de uma página de responder de forma confiável à entrada do usuário. A capacidade de resposta pode ser afetada por qualquer quantidade excessiva de trabalho que ocorra na linha de execução principal, incluindo o trabalho de renderização.

Sempre que você pode reduzir o trabalho de renderização em qualquer página, está oferecendo à linha de execução principal a oportunidade de responder às entradas do usuário mais rapidamente. Isso inclui o trabalho de renderização. O uso da propriedade CSS content-visiblity quando apropriado pode reduzir o trabalho de renderização, especialmente durante a inicialização, quando a maior parte dos trabalhos de renderização e layout é concluído.

Reduzir o trabalho de renderização tem um efeito direto no INP. Quando os usuários tentam interagir com uma página que usa a propriedade content-visibility corretamente para adiar o layout e a renderização de elementos fora da tela, você dá à linha de execução principal a chance de responder a trabalhos essenciais visíveis ao usuário. Isso pode melhorar o INP da sua página em algumas situações.

Conclusão

content-visibility e as especificações de contenção do CSS significam um desempenho incrível estão chegando diretamente ao seu arquivo CSS. Para mais informações sobre propriedades, confira: