
Uma introdução ao CSS Containment
O que é css-contain?
O principal objetivo do padrão CSS Containment é melhorar o desempenho de renderização de páginas da Web, permitindo o isolamento de uma subárvore apartir do restante do documento. Esta especificação apenas introduz uma nova propriedade CSS chamada contain
com diferentes valores possíveis. Os mecanismos do navegador podem usar essas informações para implementar otimizações e evitar fazer um trabalho extra quando souberem quais subárvores são independentes do restante da página.
Vamos explicar o que é isso e por que isso pode trazer melhorias de desempenho em sites complexos. Imagine que você tenha uma grande página HTML que gere uma árvore DOM complexa , mas você sabe que algumas partes dessa página são totalmente independentes do resto da página e o conteúdo dessas partes é modificado em algum momento.
Os mecanismos do navegador geralmente tentam evitar mais trabalho do que o necessário e usam algumas heurísticas para evitar gastar mais tempo do que o necessário. No entanto, há muitos casos de canto e situações complexas em que o navegador precisa realmente recompilar toda a página da Web. Para melhorar esses cenários, o autor deve identificar quais partes (subárvores) de seu site são independentes e isolá-las do restante da página, graças à contain
propriedade. Então, quando houver mudanças em alguns desses sub-itens, o mecanismo de renderização será capaz de evitar qualquer trabalho fora dos limites da subárvore.
Nem tudo é de graça, quando você usa, contain
existem algumas restrições que afetam esses elementos, então o navegador está totalmente certo de que pode aplicar otimizações sem causar qualquer quebra (por exemplo, você precisa definir manualmente o tamanho do elment se você quiser usar contenção de tamanho ).
A especificação de Contenção de CSS define quatro valores para a contain
propriedade, um para cada tipo de contenção :
layout
: O layout interno do elemento é totalmente isolado do resto da página, não é afetado por nada externo e seu conteúdo não pode ter nenhum efeito sobre os ancestrais.paint
: Descendentes do elemento não podem ser exibidos fora de seus limites, nada irá transbordar este elemento (ou se ele não estiver visível).size
: O tamanho do elemento pode ser calculado sem verificar seus filhos, as dimensões do elemento são independentes de seu conteúdo.style
: Os efeitos de contadores e aspas não podem escapar desse elemento, então eles são isolados do resto da página.
Observe que, em relação à contenção de estilo, há uma discussão contínua sobre o Grupo de Trabalho CSS sobre a utilidade dele (devido ao escopo mais estreito de contadores e citações).
Você pode combinar os diferentes tipos de contenção como quiser, mas a especificação também fornece dois valores extras que são uma espécie de “abreviação” para os outros quatro:
content
: O que é equivalente acontain: layout paint style
.strict
: Isso é o mesmo que ter todos os quatro tipos de contenção, então é equivalente acontain: layout paint size style
.
Exemplo
Vamos mostrar um exemplo de como a Contenção de CSS pode ajudar a melhorar o desempenho de uma página da Web.
Imagine uma página com muitos elementos, neste caso, 10.000 elementos como este:
<div class="item">
<div>Lorem ipsum...</div>
</div>
E isso modifica o conteúdo de um dos DIVs internos através do textContent
atributo.
Se você não usa css-contain, mesmo quando a alteração está em um único elemento, o Chromium gasta muito tempo no layout porque percorre toda a árvore DOM (que, nesse caso, é grande, pois possui 10.000 elementos).
Árvore de DOM de Exemplo de Contenção de CSS
Aqui é quando a contain
propriedade vem para o resgate. Neste exemplo, o DIV item
tem tamanho fixo e o conteúdo que estamos alterando no DIV interno nunca o transbordará. Assim, podemos aplicar contain: strict
ao item
, dessa forma, o navegador não precisará visitar o resto dos nós quando algo mudar dentro de um item
, ele pode parar de verificar as coisas naquele elemento e evitar ir para fora.
Observe que, se o conteúdo estourar, item
ele será cortado, e se não definirmos um tamanho fixo para o item
texto, ele será renderizado como uma caixa vazia, para que nada seja visível (na verdade, neste exemplo, as bordas estarão presentes, mas elas seria a única coisa visível).
Apesar de quão simples é cada um dos itens neste exemplo, estamos obtendo uma grande melhoria usando CSS Containment no tempo de layout indo de ~ 4ms para ~ 0,04ms, o que é uma grande diferença. Imagine o que aconteceria se a árvore DOM tivesse estruturas e conteúdos muito complexos, mas apenas uma pequena parte da página fosse modificada, se você pudesse isolar isso do resto da página, você poderia obter benefícios semelhantes.
Estado da arte
Esta não é uma especificação nova, o Chrome 52 enviou o suporte inicial até julho de 2016 , mas durante o ano passado houve algum desenvolvimento extra relacionado a ele e é isso que eu quero destacar neste post do blog.
Em primeiro lugar, muitos problemas de especificação foram corrigidos e alguns deles implicam mudanças nas implementações, a maior parte deste trabalho foi realizado por Florian Rivoal em colaboração com o CSS Working Group .
Não só isso, mas no lado dos testes, Gérard Talbot completou o conjunto de testes no repositório de testes de plataforma web (WPT) , que é realmente importante para corrigir erros nas implementações e garantir a interoperabilidade.
No meu caso , tenho trabalhado na implementação do Chromium corrigindo vários bugs e problemas de interoperabilidade e atualizando-os de acordo com as últimas alterações de especificação. Eu aproveitei o pacote de testes do WPT para fazer este trabalho e também contribuí com um monte de testes lá. Eu também importei os testes do Firefox para o Chromium para melhorar a interoperabilidade (até fiz um pequeno patch do Firefox como parte deste trabalho).
Por último, vale a pena notar que o Firefox tem trabalhado ativamente na implementação do css-contain durante o ano passado (você pode testá-lo ativando o sinalizador de tempo de execução layout.css.contain.enabled
). Espero que isso traga um segundo mecanismo de navegação para enviar as especificações no futuro.
Embrulhar
A Contenção de CSS é uma especificação simples e agradável que pode ser útil para melhorar o desempenho de renderização da Web em muitos casos de uso diferentes. É verdade que atualmente ele é suportado apenas pelo Chromium (lembre-se que o Firefox também está trabalhando nisso) e que mais melhorias e otimizações podem ser implementadas com base nele, ainda assim parece ter um enorme potencial.
Mais uma vez, todo o trabalho de Igalia relacionado ao css-contain foi patrocinado pela Bloomberg como parte de nossa colaboração contínua.
O Bloomberg tem algumas UIs complexas que estão aproveitando o css-contain para melhorar o desempenho da renderização; em futuras postagens do blog, falaremos sobre alguns desses casos e as otimizações que foram implementadas no mecanismo de renderização para melhorá-las.