Tempos de exibição de CSS e peso de renderização da página

Introdução

Se você é o tipo de pessoa que acompanha assuntos como como os navegadores funcionam, já sabe que alguns artigos incríveis foram publicados ultimamente sobre a operação composta e renderizador acelerado da GPU do Chrome. Primeiro, a Renderização acelerada no Chrome: o modelo de camadas é uma ótima introdução sobre como o Chrome usa o conceito de camadas para desenhar páginas. Para mais detalhes, a Composição acelerada de GPU no Chrome discute como o Chrome usa essas camadas, junto com a GPU para renderizar a página.

A pergunta filosófica

Depois de passar muito tempo escrevendo rastreadores de software para fins 3D, percebi que o desempenho de algumas propriedades CSS varia quando o desenho da página é variado. Por exemplo, fazer a varredura de uma imagem pequena na tela é uma operação algorítmica completamente diferente de desenhar uma sombra projetada em uma forma arbitrária. Então, a pergunta foi: como diferentes propriedades CSS afetam o peso de renderização da sua página?

Meu objetivo era categorizar um grande conjunto de propriedades/valores CSS por tempo de exibição, para que possamos criar uma compreensão de quais tipos de propriedades CSS são mais eficientes que outras. Para fazer isso, criei uma automação com fita adesiva e chiclete para tentar adicionar visibilidade numérica aos tempos de pintura do CSS, o que funcionou assim:

  • Gerar um conjunto de páginas HTML individuais, cada uma com um único elemento DOM e algumas permutações de propriedades CSS anexadas a ela.
  • Execute um script de automação que:
    • Abrir o Chrome
    • Carregar uma página
    • Produza uma imagem do Sky para a página
    • Analise cada imagem Skia tirada no Skia Benchmark para conseguir as marcações
  • Espalhe a marcação de tempo e se surpreenda com os números. (Esta parte é importante...)

Com essa configuração, geramos um conjunto de páginas HTML, em que cada página contém uma permutação exclusiva de propriedades e valores CSS. Por exemplo, aqui estão dois arquivos html:

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

E outra, que é mais complexa

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Abaixo, como variante do último exemplo, em que apenas alteramos o valor do gradiente radial:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

Cada página é, então, carregada em uma instância nova do Chrome (para garantir que o tempo não esteja enviesado por estados desatualizados nas atualizações da página), e um Skia Picture (*.SKP) é utilizado para avaliar quais comandos do Skia são usados para pintar a página. Depois que os arquivos SKP forem gerados para cada arquivo HTML, vamos executar outro lote para enviar os arquivos *.SKP por meio do aplicativo Skia Benchmark (criado a partir do código-fonte do Skia), que despeja o tempo médio necessário para renderizar essa página.

Avaliação dos dados

A partir disso, agora podemos gerar um gráfico de quanto um conjunto de propriedades CSS é necessário para pintar. Ou então, podemos começar a classificar as propriedades CSS de classificação de pilha pelo desempenho da pintura. Este é um gráfico grande feito com o Chrome 27 Beta, mostrando todo o conjunto de dados de tempo desse processo. Todos os dados estão sujeitos a alterações, conforme o Chrome se torna mais rápido e rápido com o tempo.

Tempos para todas as permutações no teste

Cada barra vertical representa o tempo de pintura de uma página com uma única combinação de propriedades CSS (ampliada em 100x.O valor em escala real desse gráfico é de 0,1,56 ms). Muitas linhas bonitas, mas nesse formato são inúteis. Precisamos fazer uma mineração de dados para encontrar tendências úteis.

Em primeiro lugar, encontramos provas de que algumas propriedades CSS são simplesmente mais caras para renderizar do que outras. Por exemplo, desenhar uma sombra de profundidade em um elemento DOM envolve uma operação de várias passagens com splines e outros tipos de coisas desagradáveis, em vez de opacidade, que deveria ser mais fácil de renderizar.

Tempo necessário para pintar um elemento que tem apenas uma propriedade CSS.

Em segundo lugar, e o mais interessante é que combinações de propriedades CSS podem ocorrer um tempo de exibição maior do que a soma das partes. Do ponto de vista de um observador, isso é um pouco estranho, esperar que A+B = C, não 2,2C. Por exemplo, adicionar box-shadow e border-radius-stroke :

Tempos para todas as permutações no teste

O que é realmente interessante sobre isso é que não é apenas a propriedade box-shadow, mas essa permutação de valores específicos. Por exemplo, abaixo mostra um agrupamento de box-shadow : 50% e border-radius com variações de valor.

Tempos para todas as permutações no teste

Analisando os dados, isso acontece por um tempo. Há muitas combinações estranhas, e meu conjunto de testes quase não toca todas elas. Ainda há vários testes e combinações que podem gerar resultados interessantes.

Como encontrar a ponderação de renderização da página

Com a capacidade de rastrear os tempos de renderização de cada elemento da página, os desenvolvedores podem começar a avaliar o peso de renderização da página e como isso afeta a capacidade de resposta do site. Confira algumas dicas para começar.

  1. Use o modo "Pintura contínua" do Chrome nas Ferramentas para desenvolvedores do Chrome para entender quais propriedades de CSS estão custando a você.
  2. Incorpore análises de CSS ao seu processo de revisão de código para detectar problemas de performance. Procure lugares no CSS em que você esteja usando itens sabidamente mais caros, como gradientes e sombras. Pergunte a si mesmo: será que eu realmente preciso deles aqui?
  3. Na dúvida, escolha sempre um melhor desempenho. Seus usuários podem não se lembrar da largura do padding nas suas colunas, mas eles vão se lembrar de como é visitar seu site.

Considerações finais

Uma das coisas mais interessantes sobre esse experimento é que o tempo vai continuar mudando a cada versão do Chrome (esperamos que fique mais rápido ;) o software de navegador é uma área de superfície em constante mudança. O que está lento hoje, pode ser rápido amanhã. Leia este artigo para evitar colocar box-shadow: 1px 2px 3px 4px em um elemento que já tenha border-radius:5. No entanto, a lição mais valiosa é que as propriedades do CSS afetam diretamente os tempos de pintura da página.

Referências