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

JavaScript è spesso l'attivatore delle modifiche visive. A volte si tratta direttamente di manipolazioni di stile, mentre a volte si tratta di calcoli che comportano modifiche visive, come la ricerca o l'ordinamento di alcuni dati. JavaScript di lunga durata o con tempi non corretti può essere una causa comune di problemi di prestazioni e, dove possibile, dovresti cercare di minimizzarne l'impatto.

La modifica del DOM tramite l'aggiunta e la rimozione di elementi, la modifica di attributi, classi o animazioni comporta il ricalcolo degli stili degli elementi e, in molti casi, del layout (o dell'adattamento dinamico del contenuto) della pagina o di parti di questi elementi. Questa procedura è chiamata calcolo di stile calcolato.

La prima parte degli stili di calcolo consiste nella creazione di un insieme di selettori corrispondenti, che essenzialmente corrisponde al browser che determina quali classi, pseudoselettori e ID si applicano a un dato elemento.

La seconda parte del processo prevede l'estrazione di tutte le regole di stile dai selettori corrispondenti per il calcolo degli stili finali dell'elemento.

Riepilogo

  • In che modo ridurre i costi di calcolo dello stile può ridurre la latenza delle interazioni.
  • Riduci la complessità dei selettori; utilizza una metodologia incentrata sulla classe (ad esempio BEM).
  • Riduci il numero di elementi su cui deve essere calcolato il calcolo dello stile.

Latenza dell'interazione e tempo di ricalcolo dello stile

Interaction to Next Paint (INP) è una metrica sulle prestazioni del runtime incentrata sull'utente che valuta l'adattabilità complessiva di una pagina all'input degli utenti. Quando la latenza di interazione viene valutata con questa metrica, questa misura il tempo a partire dal momento in cui l'utente interagisce con la pagina, fino al momento in cui il browser colora il frame successivo mostrando gli aggiornamenti visivi corrispondenti apportati all'interfaccia utente.

Un elemento importante 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 compositing. Anche se questo articolo si concentra esclusivamente sui costi di calcolo dello stile, è importante sottolineare che ridurre qualsiasi parte della fase di rendering inerente all'interazione ridurrà la latenza totale, calcolo dello stile incluso.

Riduci la complessità dei selettori

Nel caso più semplice, puoi fare riferimento a un elemento nel tuo CSS semplicemente con una classe:

.title {
  /* styles */
}

Tuttavia, man mano che qualsiasi progetto cresce, è probabile che si trasformi in CSS più complessi, così potresti ritrovarti con selettori che assomigliano a questo:

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

Per sapere come questi stili vengono applicati alla pagina, il browser deve chiedersi efficacemente "Si tratta di un elemento con una classe title che ha un elemento principale meno n° figlio più un elemento con una classe box?". Capire questo può richiedere molto tempo, a seconda del selettore utilizzato e del browser in questione. Il comportamento previsto del selettore potrebbe invece essere modificato in una classe:

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

Puoi prenderti un problema con il nome del corso, ma il lavoro è diventato molto più semplice per il browser. Nella versione precedente, per sapere, ad esempio, che l'elemento è l'ultimo del suo tipo, il browser deve prima sapere tutto di tutti gli altri elementi e se ci sono elementi successivi che potrebbero essere nth-last-child, che è potenzialmente più costoso del semplice abbinamento del selettore con l'elemento perché la sua classe corrisponde.

Riduci il numero di elementi a cui vengono assegnati stili

Un altro fattore da considerare per le prestazioni, che in genere è il fattore più importante per molti aggiornamenti di stile, è l'enorme volume di lavoro che deve essere eseguito quando un elemento viene modificato.

In generale, il costo peggiore del calcolo dello stile calcolato degli elementi è il numero di elementi moltiplicato per il numero di selettori, perché ogni elemento deve essere verificato almeno una volta su ogni stile per vedere se corrisponde.

Spesso i calcoli di stile possono avere come target alcuni elementi direttamente, invece di invalidare la pagina nel suo insieme. Nei browser moderni, questo tende a essere meno problematico perché il browser non deve necessariamente controllare tutti gli elementi potenzialmente interessati da una modifica. I browser meno recenti, invece, non sono necessariamente ottimizzati per queste attività. Dove possibile, devi ridurre il numero di elementi non più validi.

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, apri DevTools, vai alla scheda Prestazioni, premi Registra e interagisci con la pagina. Quando interrompi la registrazione, vedrai qualcosa come l'immagine di seguito:

DevTools che mostra i calcoli di stile.

La striscia in alto è un diagramma a fiamma in miniatura che traccia anche i fotogrammi al secondo. Più l'attività è vicina alla parte inferiore della striscia, più velocemente i frame vengono dipinti dal browser. Se vedi il grafico a fiamme che si livella in alto con strisce rosse sopra, significa che c'è un lavoro che causa fotogrammi lunghi.

Aumenta lo zoom su un'area problematica in Chrome DevTools nel riepilogo dell'attività del riquadro delle prestazioni popolato in Chrome DevTools.

Se durante un'interazione, come lo scorrimento, hai a disposizione un frame molto lungo, devi esaminarlo più a fondo. Se è presente un blocco viola di grandi dimensioni, aumenta lo zoom sull'attività e seleziona un'opera con l'etichetta Ricalcola stile per ottenere ulteriori informazioni su operazioni di ricalcolo dello stile potenzialmente costose.

Acquisire i dettagli dei calcoli di stile a lunga esecuzione, incluse informazioni essenziali come la quantità di elementi interessati dal lavoro di ricalcolo dello stile.

In questa situazione c'è un lavoro di ricalcolo dello stile di lunga durata che richiede poco più di 25 ms.

Se fai clic sull'evento stesso, ricevi uno stack di chiamate. Se il rendering è dovuto a un'interazione dell'utente, verrà richiamata la posizione nel codice JavaScript responsabile dell'attivazione della modifica di stile. Inoltre, ottieni il numero di elementi interessati dalla modifica (in questo caso poco più di 900 elementi) e il tempo necessario per eseguire il 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) in realtà si basano nel selettore che corrisponde ai vantaggi in termini di prestazioni sopra, perché consiglia che ogni elemento abbia una singola classe e, laddove è necessaria una gerarchia, che venga integrata anche nel nome della classe:

.list {
  /* Styles */
}

.list__list-item {
  /* Styles */
}

Se hai bisogno di un modificatore, come quello sopra per creare qualcosa di speciale per l'ultimo figlio, puoi aggiungerlo come segue:

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

Se stai cercando un modo efficace per organizzare il tuo CSS, il BEM è un buon punto di partenza, sia da un punto di vista della struttura, sia per le semplificazioni della ricerca dello stile promossa dalla metodologia.

Se il BEM non ti piace, esistono altri modi di avvicinarti al tuo CSS, ma le considerazioni sul rendimento dovrebbero essere valutate insieme all'ergonomia dell'approccio.

Risorse

Immagine hero di Unsplash, di Markus Spiske.