Tempi di paint CSS e peso del rendering della pagina

Colt McAnlis
Colt McAnlis

Introduzione

Se sei il tipo di persona che si tiene al passo con aspetti come il funzionamento dei browser, saprai già che di recente sono stati pubblicati alcuni articoli straordinari che descrivono l'operazione di rendering/composizione con accelerazione GPU di Chrome. Innanzitutto, Rendering accelerato in Chrome: il modello a livelli è un'ottima introduzione a come Chrome utilizza il concetto di livelli per disegnare la pagina. Per approfondire, Compositing accelerato GPU in Chrome illustra come Chrome utilizza questi livelli insieme alla GPU per il rendering della pagina.

La domanda filosofica

Dopo aver trascorso molto tempo a scrivere rasterizzatori software per scopi 3D, mi è apparso chiaro che alcune proprietà CSS dovrebbero avere un rendimento diverso durante il disegno della pagina. Ad esempio, la rasterizzazione di una piccola immagine sullo schermo è un'operazione algoritmica completamente diversa rispetto al disegno di un'ombra su una forma arbitraria. La domanda è diventata: In che modo le diverse proprietà CSS influiscono sul peso di rendering della pagina?

Il mio obiettivo era classificare un ampio insieme di proprietà/valori CSS in base ai tempi di aggiornamento, in modo da capire quali tipi di proprietà CSS hanno un rendimento migliore rispetto ad altre. Per farlo, ho scritto un po' di automazione con nastro adesivo e gomma da masticare per tentare di aggiungere visibilità numerica ai tempi di aggiornamento CSS, che funzionavano nel seguente modo:

  • Genera una suite di singole pagine HTML, ognuna con un singolo elemento DOM e alcune permutazioni di proprietà CSS associate.
  • Esegui uno script di automazione che, per ogni pagina:
    • Avvia Chrome
    • Caricare una pagina
    • Crea un'immagine Skia per la pagina
    • Esegui ogni immagine Skia acquisita tramite Skia Benchmark per ottenere i tempi
  • Visualizza tutti i tempi e ammira i numeri. (Questa parte è importante…)

Con questa configurazione, generiamo una suite di pagine HTML, in cui ogni pagina contiene una permutazione univoca di proprietà e valori CSS. Ad esempio, di seguito sono riportati due file 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>

Un altro, più complesso

<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>

Di seguito è riportata una variante dell'ultimo esempio, in cui modifichiamo solo il valore della sfumatura radiale:

<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>

Ogni pagina viene quindi caricata in un'istanza nuova di Chrome (per garantire che i tempi non siano stati in qualche modo alterati da stati non aggiornati nei ricaricamenti della pagina) e viene acquisita un'immagine Skia (*.SKP) per valutare quali comandi Skia vengono utilizzati per dipingere la pagina. Una volta generati i file SKP per ogni file HTML, eseguiamo un altro batch per inviare i file *.SKP all'applicazione Skia Benchmark (creata dal codice sorgente di Skia), che stampa il tempo medio impiegato per il rendering della pagina.

Valutazione dei dati

Da ciò, ora abbiamo la possibilità di tracciare in modo approssimativo il tempo necessario per la visualizzazione di una suite di proprietà CSS. In altre parole, possiamo iniziare a classificare le proprietà CSS in base al loro rendimento di pittura. Ecco un grafico di grandi dimensioni ottenuto con Chrome 27 beta che mostra l'intero insieme di dati relativi ai tempi di questo processo. Tieni presente che tutti i dati sono soggetti a modifiche man mano che Chrome diventa sempre più veloce nel tempo.

Tempi di tutte le permutazioni nel test

Ogni barra verticale rappresenta il tempo di aggiornamento di una pagina con una singola combinazione di proprietà CSS (ingrandita 100 volte; il valore in scala reale di questo grafico è 0,156 ms). Molte linee belle, ma in questa forma sono un po' inutili; dobbiamo eseguire del data mining per trovare tendenze utili.

Innanzitutto, abbiamo la prova che alcune proprietà CSS sono semplicemente più costose da eseguire in rendering rispetto ad altre. Ad esempio, disegnare un'ombra su un elemento DOM comporta un'operazione con più passaggi con spline e altri tipi di elementi complicati, rispetto all'opacità che dovrebbe essere più facile da eseguire.

Tempo necessario per dipingere un elemento con una sola proprietà CSS

In secondo luogo, e più interessante, le combinazioni di proprietà CSS possono avere un tempo di rendering maggiore della somma delle loro parti. Dal punto di vista di un osservatore, è un po' strano, ci aspetteremmo che A + B = C, non 2,2 C. Ad esempio, aggiungendo box-shadow e border-radius-stroke :

Tempi di tutte le permutazioni nel test

La cosa davvero interessante è che non si tratta solo della proprietà box-shadow stessa, ma piuttosto della permutazione specifica del valore. Ad esempio, di seguito è riportato un raggruppamento di box-shadow : 50% e border-radius con variazioni di valore.

Tempi di tutte le permutazioni nel test

Se guardiamo i dati, questo problema si verifica da un po' di tempo. Esistono molte combinazioni diverse e la mia suite di test non le copre tutte; ci sono ancora tantissimi test e combinazioni che potrebbero produrre risultati interessanti

Trovare il peso di rendering della pagina

Grazie alla possibilità di monitorare i tempi di rendering di ciascun elemento della pagina, gli sviluppatori possono iniziare a valutare il peso del rendering della pagina e il suo impatto sulla reattività del sito. Ecco alcuni suggerimenti per iniziare.

  1. Utilizza la modalità di disegno continuo di Chrome in Chrome DevTools per capire quali proprietà CSS ti stanno costando.
  2. Incorpora le revisioni CSS nella procedura di revisione del codice esistente per rilevare i problemi di prestazioni. Cerca nel CSS i punti in cui utilizzi elementi noti per essere più costosi, come gradienti e ombre. Chiediti se hai davvero bisogno di questi elementi qui.
  3. In caso di dubbio, scegli sempre il rendimento migliore. Gli utenti potrebbero non ricordare la larghezza del padding delle colonne, ma ricorderanno l'esperienza di visita del tuo sito.

Considerazioni finali

Una delle cose più interessanti di questo esperimento è che i tempi continueranno a cambiare con ogni versione di Chrome (si spera più veloce ;), perché il software del browser è una superficie in continua evoluzione. Ciò che è lento oggi potrebbe essere veloce domani. Potresti rimuovere questo articolo per evitare di inserire box-shadow: 1px 2px 3px 4px in un elemento che ha già border-radius:5. Tuttavia, la cosa più importante da ricordare è che le proprietà CSS influiscono direttamente sui tempi di aggiornamento della pagina.

Riferimenti