Il Critical Rendering Path o (Percorso di Rendering Critico) è la sequenza di operazioni che il browser esegue per il primo rendering di una pagina sullo schermo, cioè per scaricare, elaborare e convertire codice HTML, CSS e JavaScript in pixel reali, e visualizzarli graficamente sullo schermo.

L’Ottimizzazione del Critical Rendering Path è il processo di riduzione al minimo del tempo impiegato dal browser per eseguire ogni fase della sequenza, dando priorità alla visualizzazione dei contenuti relativi all’azione corrente dell’utente.

Gran parte di questo processo riguarda la porzione di pagina visibile senza scorrere la finestra del browser. Questa sezione è conosciuta anche come “Above the Fold“. Per una migliore usabilità, l’ATF dovrebbe essere reso a video il più presto possibile, e questo può essere realizzato riducendo al minimo il numero dei round trip di rete. Le risorse necessarie per il rendering dell’ATF sono considerate critiche, e ottimizzare l’Above the Fold significa minimizzare l’impatto delle risorse critiche sul tempo del primo rendering della pagina.

In questo articolo, analizzeremo la sequenza di ottimizzazione del Percorso di Rendering Critico.

  • In primo luogo, fornirò una panoramica generale dei task eseguiti dal browser per rendere il contenuto di una pagina.
  • In seguito, analizzerò le azioni più rilevanti che possiamo intraprendere per ottimizzare il Percorso di Rendering Critico.
  • Infine, elencherò alcuni utili (e popolari) plugin di ottimizzazione di WordPress.

La Sequenza del Percorso di Rendering Critico

Ecco la sequenza dei passaggi eseguiti dal browser per rendere una pagina:

  • In primo luogo, il browser scarica e analizza il mark-up HTML e costruisce il DOM
  • Poi scarica ed elabora il mark-up CSS e costruisce il CSS Object Model
  • Combina i nodi DOM e CSSOM necessari per rendere la pagina nel Render Tree, che è una struttura ad albero di tutti i nodi visibili
  • Calcola le dimensioni e la posizione di ogni oggetto nella pagina
  • Infine dipinge i pixel sullo schermo

Il DOM

Come spiegato anche nella Guida all’Ottimizzazione del Percorso di Rendering Critico di Google, il browser costruisce il Document Object Model in una sequenza di quattro passaggi:

  • In primo luogo, il browser legge i byte delle righe e li traduce in singoli caratteri
  • Poi converte le stringhe di caratteri racchiuse tra parentesi angolari in token
  • Questi token vengono convertiti in oggetti nodo
  • Gli oggetti nodo sono collegati tra loro in una struttura dati ad albero che contiene contenuti HTML, proprietà e tutte le relazioni tra i nodi. Questa struttura è il Document Object Model.

Ciò che è importante notare qui è che il browser costruisce il DOM in modo incrementale. Questo ci dà l’opportunità di velocizzare il rendering della pagina creando strutture DOM efficienti.

Struttura del DOM
Struttura del DOM

Il CSSOM

Quando il parser incontra un tag link che si riferisce ad un foglio di stile CSS esterno, blocca il parsing e invia una richiesta per questa risorsa. Una volta ricevuto il file CSS, il browser inizia a costruire una struttura dati ad albero dei nodi CSS.

  • Il browser legge i byte delle righe del file .css e li traduce in singoli caratteri
  • Converte le stringhe di caratteri racchiuse tra parentesi graffe in token
  • Questi token vengono convertiti in oggetti nodo
  • Gli oggetti nodo sono collegati in una struttura dati ad albero che contiene le proprietà CSS di ogni nodo e le relazioni tra i nodi. Questa struttura è il CSS Object Model (CSSOM).

A differenza della costruzione del DOM, la costruzione del CSSOM non è incrementale. Il browser non può utilizzare una porzione di un foglio di stile, perché gli stili possono essere ridefiniti e ridichiarati nello stesso foglio di stile. Per questo motivo, il browser blocca il processo di rendering fino a quando non riceve e analizza tutti i CSS. Ciò significa che CSS blocca il rendering.

Struttura CSSOM
Struttura CSSOM

Il Render Tree

Il browser combina DOM e CSSOM nel Render Tree, che è la struttura ad albero finale contenente tutti i nodi e le proprietà che vengono utilizzati per rendere la pagina sullo schermo.

Il Render Tree contiene solo i nodi necessari per rendere una pagina. Di conseguenza, i nodi invisibili vengono omessi.

Il browser utilizza il Render Tree per calcolare le dimensioni e la posizione del nodo e, in ultima analisi, come input per il processo di resa a video.

Struttura del Render Tree
Struttura del Render Tree

Layout e Resa a Video

Nella fase di layout, il browser calcola le dimensioni e la posizione di ogni nodo del Render Tree. In questa fase, il browser attraversa il Render Tree partendo dalla sua radice e produce un box model. Queste informazioni vengono infine utilizzate per convertire ogni nodo del Render Tree in pixel reali sullo schermo.

Ottimizzazione del Percorso di Rendering Critico

Il tempo necessario per eseguire l’intero processo può essere variabile. Dipende da molti fattori, come la dimensione del documento, il numero di richieste, gli stili applicati, il dispositivo dell’utente, ecc.
Una delle raccomandazioni più rilevanti di Google è quella di dare priorità ai contenuti visibili, in modo da rendere il più veloce possibile la parte Above the Fold e fornisce due regole principali da seguire:

  • Strutturare l’HTML in modo che carichi prima il contenuto critico, Above the Fold
  • Ridurre la quantità di dati utilizzati dalle risorse HTML, CSS e JS

Come ben spiegato nella guida di PageSpeed di Google, se la quantità di dati necessari per rendere l’ATF supera la finestra di congestione iniziale (14,6kb), saranno necessari altri round trip di rete tra il server e il browser. Sulle reti mobili, con latenze elevate, ciò ritarderebbe notevolmente il caricamento delle pagine (per saperne di più sulla latenza).
Il browser costruisce il DOM in modo incrementale, e questo ci dà l’opportunità di ridurre il tempo necessario per rendere l’ATF strutturando l’HTML in modo da caricare prima l’above the fold e rimandare il resto della pagina.

Il contenuto Above the Fold varia a seconda del dispositivo utente
Il contenuto Above the Fold varia a seconda del dispositivo utente

Ma l’ottimizzazione non si esaurisce con la costruzione di una struttura DOM efficiente. Si tratta piuttosto di un processo di miglioramento e di misurazione che coinvolge l’intera sequenza del Percorso di Rendering Critico.

Approfondiamo.

Minimizzate le Dimensioni delle Risorse

Possiamo ridurre la quantità di dati che il browser sta per scaricare tramite la minificazione, la compressione e il caching delle risorse HTML, CSS e JavaScript:

  • La minimizzazione è il processo di rimozione dei caratteri non necessari, come i commenti e gli spazi bianchi, dal codice sorgente. Questi caratteri sono estremamente utili nello sviluppo, ma non servono al browser per rendere la pagina.
  • La compressione è la capacità dei server web e dei client di ridurre le dimensioni dei file trasmessi al fine di migliorare la velocità e l’utilizzo della larghezza di banda
  • La cache: ogni browser viene fornito con un’implementazione di una cache HTTP. Quello che dobbiamo fare è assicurarci che ogni risposta del server fornisca gli header HTTP corretti per istruire il browser su quando e per quanto tempo deve mettere in cache le risorse richieste

Ottimizzate i CSS

Ora sappiamo che il browser deve attendere che recuperi ed elabori il codice CSS prima di poter rendere la pagina (CSS blocca il rendering). Ma non tutte le risorse CSS bloccano il rendering.
I CSS possono essere adattati a condizioni particolari, e possiamo ottimizzarli utilizzando i media type e le media query. Se state visualizzando una pagina web sullo schermo, il browser invierà una richiesta per il media type di stampa, ma non bloccherà il rendering della pagina per questa risorsa.
Prendete il seguente tag di link:

<link rel="stylesheet" href="style.css" />

Il foglio di stile di riferimento di questo tag si applica in qualsiasi condizione, indipendentemente dal tipo di supporto corrente, dalla risoluzione dello schermo, dall’orientamento del dispositivo, ecc. Questo significa che la risorsa CSS blocca sempre il rendering.
Fortunatamente, possiamo inviare una richiesta per una risorsa CSS a condizioni specifiche. Potremmo spostare gli stili per la stampa in un file separato e usare l’attributo media per dire al browser che il foglio di stile specificato deve essere caricato solo quando si stampa la pagina, e non ha bisogno di bloccare il rendering sullo schermo:

<link rel="stylesheet" href="print.css" media="print" />

Il browser scarica ancora il foglio di stile print.css, ma non blocca il rendering. Inoltre, il browser deve scaricare meno dati per il file CSS principale e questo ci aiuterebbe a velocizzare il download. Possiamo specificare qualsiasi media query sull’attributo link, in modo da poter dividere i CSS in più file e caricarli in via condizionale:

<link rel="stylesheet" href="style.css" media="screen" />
<link rel="stylesheet" href="portrait.css" media="orientation:portrait" />
<link rel="stylesheet" href="widescreen.css" media="(min-width: 42rem)" />

Assicuratevi che i vostri stili siano effettivamente necessari per rendere la pagina. Se non lo sono, potreste aggiungere un valore appropriato all’attributo media del tag e sbloccare il rendering.

I media type e le query possono aiutarci a velocizzare il rendering delle pagine, ma possiamo fare molto di più.

  • Minificare CSS: gli spazi bianchi e i commenti ci aiutano solo a leggere le dichiarazioni CSS. Rimuovendo i commenti e gli spazi bianchi dal foglio di stile possiamo ridurre significativamente il numero di byte di un file CSS
  • Combinare più file CSS: questo ridurrebbe il numero di richieste HTTP. Questa azione è particolarmente importante nelle connessioni mobili, dove le prestazioni sono influenzate da un’elevata latenza (per saperne di più sulla latenza).
  • Inserire in linea i CSS critici: alcuni stili sono critici nel senso che sono necessari per rendere l’above the fold della pagina. Dovreste sempre considerare la possibilità di inserire gli stili critici in linea direttamente nel markup HTML, per evitare ulteriori richieste HTTP. Ma evitate l’inlining di file CSS di grandi dimensioni, perché questo potrebbe richiedere ulteriori round trip per rendere l’Above the Fold, e questo si tradurrebbe in un avviso di PageSpeed.

Potete dare un bell’impulso al vostro sito minificando il codice direttamente dal vostro cruscotto MyKinsta. È sufficiente usare la funzione di minificazione del codice messa a disposizione per attivare la modifica automatica di CSS e Javascript con un semplice clic.

Velocizzare i Processi di Layout e Resa a Video

Il tempo impiegato dal browser per impaginare il documento dipende dal numero di elementi del DOM da impaginare e dalla complessità del layout.

  • Se avete molti elementi del DOM, il browser potrebbe richiedere molto tempo per calcolare la posizione e le dimensioni di tutti gli elementi: evitate il layout ogni volta che è possibile.
  • Preferite il nuovo modello Flexbox, in quanto è più veloce del vecchio Flexbox e dei layout float.
  • Evitate di forzare il layout sincrono con JavaScript

Il calcolo delle dimensioni e della posizione degli elementi richiede tempo e riduce le prestazioni. Rendere il DOM il più semplice possibile ed evitare l’uso di JavaScript per anticipare il processo di layout aiuterebbe il browser a velocizzare il rendering delle pagine (per saperne di più sull’ottimizzazione del layout).

Strettamente connesso al Layout è il processo di resa grafica, che è probabilmente la fase che richiede più tempo nella sequenza del Critical Rendering Path perché, ogni volta che si modifica il layout di un elemento o qualsiasi proprietà non geometrica, il browser attiva un evento paint. Fare le cose nel modo più semplice possibile in questa fase potrebbe aiutare il browser ad accelerare il processo di visualizzazione. Per esempio, una proprietà box-shadow, che richiede qualche tipo di calcolo, richiederebbe più tempo di un colore di bordo solido.

Chrome DevTools permette di identificare le porzioni di pagina che vengono dipinte
Chrome DevTools permette di identificare le porzioni di pagina che vengono dipinte

L’ottimizzazione del processo di resa grafica (paint) può non essere così facile, e si dovrebbero utilizzare gli strumenti di sviluppo del browser per misurare il tempo che il browser impiega per attivare ogni evento paint. Potete leggere di più su questo argomento nella guida Rendering Performance di Google.

Evitare che JavaScript Blocchi il Rendering

Quando il browser incontra un tag script, deve interrompere il parsing del codice HTML. Gli script in linea vengono eseguiti nel punto esatto in cui si trovano nel documento e bloccano la costruzione del DOM fino a quando il motore JS termina la sua esecuzione. In altre parole, JavaScript in linea può ritardare notevolmente il rendering iniziale della pagina. Ma JavaScript permette anche di manipolare le proprietà CSS, quindi il browser deve mettere in pausa l’esecuzione dello script fino a quando non ha finito di scaricare e costruire il CSSOM. Ciò significa che JavaScript causa il blocco del parsing.

Nel caso di file JS esterni, il parser deve anche attendere che la risorsa sia stata recuperata dalla cache o dal server remoto, e questo potrebbe rallentare pesantemente il tempo necessario al primo rendering della pagina.
Detto questo, cosa possiamo fare per ridurre al minimo il tempo impiegato dal browser per caricare ed eseguire JavaScript?

  • Caricare JavaScript in modo asincrono: l’attributo booleano async del tag script istruisce il browser ad eseguire lo script in modo asincrono, se possibile, senza bloccare la costruzione del DOM. Il browser invia la richiesta HTTP per lo script e continua il parsing del DOM. Inoltre, lo script non blocca la costruzione del CSSOM, il che significa che non bloccherà il Critical Rendering Path (si veda la documentazione di MDN per maggiori informazioni sugli attributi dei tag script)
  • Differire JavaScript: l’attributo booleano defer del tag script dice al browser di eseguire lo script dopo l’analisi del documento, ma prima di avviare l’evento DOMContentLoaded. Questo attributo non deve essere usato se l’attributo src è assente, cioè negli script in linea (per saperne di più, si legga Mozilla Hacks)
  • Posticipare il codice JavaScript in linea: molti script non manipolano il DOM o il CSSOM, quindi non c’è alcuna ragione per bloccare il parsing. Sfortunatamente, non possiamo usare gli attributi async e defer per gli script in linea, quindi l’unico modo per caricarli dopo che il documento è stato caricato è spostarli in basso. Il vantaggio è che gli script in linea non richiedono altre richieste HTTP. Tuttavia, inserire gli script in linea quando questi sono utilizzati in diverse pagine sarebbe ridondante.

Riepilodo delle Regole di Ottimizzazione

Sono un sacco di cose da ricordare, vero? Tiriamo un attimo il fiato e facciamo un riepilogo delle azioni di ottimizzazione descritte finora.

  • Minimizzare, comprimere e mettere in cache le risorse HTML, CSS e JavaScript.
  • Ridurre al minimo l’utilizzo di risorse che bloccano il rendering (in particolare CSS)
    • Utilizzare le media query sui tag link
    • Dividere i fogli di stile e inserire in linea i CSS critici
    • Combinare più file CSS
  • Ridurre al minimo l’utilizzo di risorse che bloccano il parser (JavaScript)
    • Utilizzare l’attributo defer sui tag script
    • Utilizzare l’attributo async sui tag script
    • Inserire JavaScript in linea e spostare i tag script in fondo al documento

Ora che conosciamo i concetti di base dell’Ottimizzazione del Critical Rendering Path, possiamo dare un’occhiata ad alcuni popolari plugin di ottimizzazione di WordPress.

Ottimizzare il Critical Rendering Path in WordPress

Gli utenti di WordPress possono usufruire di una serie di plugin che coprono quasi ogni fase del processo di ottimizzazione. Si può installare un plugin completo, oppure si possono installare più plugin contemporaneamente, ognuno dei quali fornisce specifiche funzionalità di ottimizzazione.

Se il vostro sito è ospitato da Kinsta, non avrete bisogno di un plugin per il caching perché non sono necessari plugin per il caching di WordPress su Kinsta.

W3 Cache totale

Questo singolo plugin copre quasi tutte le fasi del processo di ottimizzazione del Percorso di Rendering Critico. A prima vista la configurazione del plugin può essere scoraggiante, ma una volta acquisita una maggiore familiarità con la sequenza del Critical Rendering Path, si potrà beneficiare di un potente set di strumenti di performance.

W3 Totale Cache WordPress
W3 Totale Cache WordPress

Ecco un elenco di alcune funzionalità del plugin:

  • Cache HTML (post e pagine), CSS e JavaScript in memoria, su disco o su CDN
  • Cache di feed, risultati di ricerca, oggetti database, oggetti WordPress e frammenti
  • Minimizzazione di HTML (post e pagine)
  • Minimizzazione di JavaScript e CSS
  • Ottimizzazione di JavaScript con async e defer
  • Cache del browser con controllo della cache, header expire futuri e tag entity
  • Compressione HTTP (gzip)
  • Risultati di Google PageSpeed sul cruscotto di WordPress

Queste sono solo alcune delle tante caratteristiche di W3TC. Potete leggere di più su tutte le funzionalità, le impostazioni e le opzioni del plugin in questa guida dettagliata.

Impostazioni di minimizzazione di W3 Total Cache JavaScript
Impostazioni di minimizzazione di W3 Total Cache JavaScript

WP Super Cache

WP Super Cache è un altro popolare plugin per le prestazioni del sito.

Il plugin WordPress WP Super Cache
Il plugin WordPress WP Super Cache

Il plugin è dotato di un buon numero di funzioni di ottimizzazione, ma è meno completo del precedente W3 Total Cache e può sembrare più accessibile ad utenti principianti e intermedi.

WordPress Super Cache tester
WordPress Super Cache tester

Di base, offre funzionalità di cache e compressione HTTP, ma manca di minimizzazione delle risorse e di ottimizzazione JavaScript con gli attributi async e defer. Tuttavia, più di un milione di installazioni attive dimostrano che il plugin merita di essere provato.

Opzione GZIP in WP Super Cache
Opzione GZIP in WP Super Cache

Autoptimize

Con oltre 1.000.000 installazioni attive, Autoptimize è uno dei plugin gratuiti più popolari per la minificazione.

Il plugin WordPress Autoptimize
Il plugin WordPress Autoptimize

Viene fornito con una pagina di opzioni suddivisa in diverse sezioni dove l’amministratore del sito può configurare separatamente la minificazione di HTML, CSS e JavaScript.

Opzione di ottimizzazione automatica HTML
Opzione di ottimizzazione automatica HTML

È anche possibile aggregare script o fogli di stile indipendenti e impostare eccezioni per risorse specifiche. Inoltre, Autoptimize permette di mettere in cache le risorse minificate su disco o su CDN e di salvare le risorse ottimizzate come file statici. Per trovare le migliori impostazioni per il vostro sito WordPress potete seguire la nostra guida dettagliata su Autoptimize.

Altri plugin di ottimizzazione da provare:

Swift Performance

Swift Performance è un altro plugin cui potreste dare un’occhiata. Si tratta di un plugin premium che può aiutarvi ad aumentare i vostri punteggi di performance, ed è stato sviluppato appositamente per aiutarvi a raggiungere quel famoso 100/100 su Google PageSpeed Insights.

Il plugin WordPress Swift Performance
Il plugin WordPress Swift Performance

Alcune delle sue funzionalità principali includono:

  • Non solo si possono minificare e combinare file CSS e JavaScript, ma si possono creare CSS critici al volo per le vostre pagine.
  • Cache intelligente, AJAX e richieste dinamiche.
  • Compressione delle immagini senza perdita di dati.
  • Supporto CDN.

Troverete una descrizione più approfondita dei plugin di ottimizzazione di WordPress in Come Eliminare JavaScript e CSS che Bloccano il Rendering.

Conclusioni

L’ottimizzazione del percorso di rendering critico è un processo di miglioramento e misurazione che richiede una chiara comprensione di ogni task eseguito dal browser per convertire il codice in pixel e quindi per rendere una pagina sullo schermo. Potete saperne di più sul Critical Rendering Path nella guida all’ottimizzazione di Google.

Qui, sul blog di Kinsta, cerchiamo di analizzare tutti gli aspetti dell’ottimizzazione delle performance. Ecco un elenco di altre letture:

Quanto tempo vi occorre per ottimizzare il Percorso di Rendering Critico dei vostri siti web? E quali aspetti del processo di ottimizzazione sono i più difficili da gestire? Scrivetecelo nei commenti qui sotto.