Riduci l'ambito e la complessità dei calcoli di stile

JavaScript è spesso un attivatore delle modifiche visive. A volte le modifiche vengono apportate direttamente tramite manipolazioni dello stile, a volte tramite calcoli che comportano modifiche visive, come la ricerca o l'ordinamento dei dati. JavaScript di lunga durata o con tempi non corretti può essere una causa comune di problemi di prestazioni e, se possibile, dovresti cercare di minimizzarne l'impatto.

Calcolo dello stile

La modifica del DOM tramite l'aggiunta e la rimozione di elementi, la modifica di attributi, classi o animazioni fa sì che il browser ricalcoli gli stili degli elementi e, in molti casi, il layout di una parte o di tutta la pagina. Questa procedura è chiamata calcolo di stile calcolato.

Il browser inizia a calcolare gli stili creando un insieme di selettori corrispondenti per determinare quali classi, pseudoselettori e ID si applicano a un determinato elemento. Quindi, elabora le regole di stile dai selettori corrispondenti e determina gli stili finali dell'elemento.

Latenza dell'interazione e tempo di ricalcolo dello stile

Interaction to Next Paint (INP) è una metrica sulle prestazioni di runtime incentrata sull'utente che valuta l'adattabilità complessiva di una pagina all'input dell'utente. Misura la latenza dell'interazione da quando l'utente interagisce con la pagina fino a quando il browser colora il frame successivo mostrando gli aggiornamenti visivi corrispondenti all'interfaccia utente.

Un componente significativo di un'interazione è il tempo necessario per colorare il frame successivo. Il lavoro di rendering eseguito per presentare il frame successivo è costituito da molte parti, compreso il calcolo degli stili di pagina che si verificano immediatamente prima delle operazioni di layout, colorazione e composizione. Questa pagina è incentrata sui costi di calcolo dello stile, ma riducendo qualsiasi parte della fase di rendering relativa all'interazione riduce anche la sua latenza totale, inclusi i calcoli di stile.

Riduci la complessità dei selettori

Semplificare i nomi dei selettori può contribuire a velocizzare i calcoli dello stile della pagina. I selettori più semplici fanno riferimento a un elemento in CSS solo con un nome di classe:

.title {
  /* styles */
}

Tuttavia, man mano che un progetto cresce, è probabile che abbia bisogno di un CSS più complesso e alla fine potresti ottenere selettori simili al seguente:

.box:nth-last-child(-n+1) .title {
  /* styles */
}

Per determinare come questi stili vengono applicati alla pagina, il browser deve chiedersi efficacemente "Si tratta di un elemento con classe title il cui padre è l'elemento secondario meno-nth-plus-1 con classe box?" Capire questo può richiedere molto tempo, a seconda del selettore utilizzato e del browser in questione. Per semplificare, puoi cambiare il selettore in modo che sia solo il nome di un corso:

.final-box-title {
  /* styles */
}

Questi nomi di classi sostitutive possono sembrare imbarazzanti, ma rendono il lavoro del browser molto più semplice. Nella versione precedente, ad esempio, affinché il browser sappia che un elemento è l'ultimo del suo tipo, deve prima sapere tutto di tutti gli altri elementi per determinare se eventuali elementi successivi potrebbero essere nth-last-child. Questo può essere molto più costoso dal punto di vista dell'elaborazione rispetto all'abbinamento di un selettore a un elemento solo perché la sua classe corrisponde.

Riduci il numero di elementi a cui vengono assegnati stili

Un'altra considerazione delle prestazioni, spesso più importante della complessità del selettore, è la quantità di lavoro che deve essere svolta quando un elemento cambia.

In generale, il costo peggiore per il calcolo dello stile degli elementi calcolati è il numero di elementi moltiplicato per il numero del selettore, perché il browser deve controllare ogni elemento almeno una volta rispetto a ogni stile per vedere se corrisponde.

I calcoli di stile possono avere come target alcuni elementi direttamente, invece di invalidare l'intera pagina. Nei browser moderni, questo tende a essere meno problematico perché il browser non ha sempre bisogno di controllare tutti gli elementi interessati da una modifica. I browser meno recenti, invece, non sono sempre ottimizzati per queste attività. Dove è possibile, devi ridurre il numero di elementi invalidati.

Misura il costo di ricalcolo dello stile

Un modo per misurare il costo dei ricalcoli dello stile è utilizzare il riquadro delle prestazioni in Chrome DevTools. Per iniziare:

  1. Apri DevTools.
  2. Vai alla scheda Rendimento.
  3. Fai clic su Record (Registra).
  4. Interagire con la pagina.

Quando interrompi la registrazione, vedrai un'immagine simile alla seguente immagine:

DevTools che mostra i calcoli di stile.
Un report DevTools che mostra i calcoli di stile.

La striscia in alto è un diagramma a fiamma in miniatura che traccia anche i frame al secondo. Più l'attività è vicina alla parte inferiore della striscia, più i frame più veloci vengono dipinti dal browser. Se vedi che il grafico a fiamma si livella in alto con barre rosse sopra, significa che è presente del lavoro che causa frame di lunga durata.

Aumenta lo zoom su un'area problematica in Chrome DevTools nel riepilogo dell'attività del riquadro delle prestazioni compilato in Chrome DevTools.
Frame a lunga esecuzione nel riepilogo delle attività di DevTools.

Vale la pena esaminare più da vicino i frame lunghi durante un'interazione come lo scorrimento. Se vedi un blocco viola di grandi dimensioni, ingrandisci l'attività e seleziona un'opera con l'etichetta Ricalcola stile per ottenere ulteriori informazioni su operazioni di ricalcolo dello stile potenzialmente costose.

Recupero dei dettagli dei calcoli di stile a lunga esecuzione, incluse informazioni essenziali come la quantità di elementi interessati dal lavoro di ricalcolo dello stile.
Un ricalcolo di stile a lunga esecuzione che richiede poco più di 25 ms nel riepilogo DevTools.

Se fai clic sull'evento, viene visualizzato il relativo stack di chiamate. Se il lavoro di rendering è stato causato da un'interazione utente, richiama il codice JavaScript che ha attivato la modifica di stile. Mostra inoltre il numero di elementi interessati dalla modifica (in questo caso poco più di 900 elementi) e la durata del calcolo dello stile. Puoi utilizzare queste informazioni per iniziare a cercare una correzione nel codice.

Usa Blocco, Elemento, Modificatore

Approcci alla programmazione come BEM (Block, Element, Modifier) integrano nel selettore i vantaggi in termini di prestazioni. BEM consiglia che tutti gli elementi abbiano un'unica classe e, laddove serve una gerarchia, anche questa gerarchia viene integrata nel nome della classe:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

Se hai bisogno di un modificatore, come nell'esempio dell'ultimo elemento secondario, puoi aggiungerlo come segue:

.list__list-item--last-child {
  /* Styles */
}

BEM è un buon punto di partenza per organizzare il tuo CSS, sia dal punto di vista della struttura, sia per le semplificazioni della ricerca di stile che promuove.

Se non ti piace il BEM, ci sono altri modi di avvicinarti al tuo CSS, ma dovresti valutarne le prestazioni e l'ergonomia prima di iniziare.

Risorse

Immagine hero di Unsplash, di Markus Spiske.