Sommario
Differire il caricamento di un foglio di stile
Differire il caricamento di una parte dei fogli di stile è tra le operazioni che si possono attuare per velocizzare il tempo di visualizzazione dei contenuti di una pagina. Per i file JavaScript questo differimento si effettua in maniera abbastanza intuitiva tramite gli attributi defer e async del tag <script>
. Purtroppo gli stessi non sono disponibili per il tag <link>
con cui si include il codice CSS.
Il rendering
Ma andiamo per gradi. Dopo avere richiesto ed ottenuto da un server la pagina web con tutte le risorse correlate (file CSS, JavaScript, immagini…), il browser è impegnato in un’operazione complessa che consiste nel determinare l’aspetto della pagina.
Questo processo durante il quale il browser visualizza la pagina sullo schermo si definisce rendering: nello specifico inizialmente si calcolano le dimensioni e la posizione degli elementi (fase di layout), successivamente vengono rappresentati e disegnati a video (fase di paint).
Il CRP
Il Percorso Critico di Rendering (in inglese: Critical Rendering Path, CRP) è la sequenza di passi che il browser compie per convertire HTML, CSS e Javascript in pixel sullo schermo
developer.mozilla.org
I CSS sono delle risorse bloccanti per il rendering (render-blocking resources). Questo significa che il browser blocca il rendering di una pagina finché non riceve e processa tutto il CSS, il caricamento è sincrono perché avviene contestualmente al rendering.
Il motivo è che i fogli di stile vengono ritenuti a buon diritto indispensabili, del resto le dimensioni, posizione e l’aspetto dei nodi dell’HTML vengono determinati tramite i CSS che, pertanto, devono essere caricati ed interpretati prima che il browser esegua il rendering della pagina. Per inciso anche i file JavaScript, insieme ovviamente all’HTML, sono risorse sincrone e bloccanti.
Best practices
Solitamente per rendere meno gravoso il CRP si consiglia di:
- ridurre il numero di richieste al server (per esempio inglobando più file in uno solo);
- diminuire il peso in KB delle risorse (ottimizzando il codice e minificandolo);
- ottimizzare l’ordine in cui vengono caricate le risorse assegnando la priorità al download delle risorse critiche (quello di cui stiamo parlando appunto in questo post con riferimento particolare ai fogli di stile).
Le risorse non critiche
L’ultimo punto ci porta dritti al concetto di criticità di una risorsa. Una risorsa è critica quando concorre alla visualizzazione dei contenuti above the fold, in altre parole quelli visualizzati come primi (o tra i primi) senza l’uso della barra di scorrimento. Si consideri anche che il browser è già in grado di riconoscere automaticamente alcuni CSS non critici dal loro attributo media.
Un browser impegnato a renderizzare una pagina su un dispositivo desktop comprenderà che questi due fogli di stile non sono critici, in quanto il primo evidentemente destinato alla visualizzazione per i dispositivi mobili, il secondo alla stampa della pagina. In questo caso i due file verranno comunque scaricati ma in maniera asincrona e non bloccante, quindi dopo il rendering della pagina.
Estrarre i CSS non critici
Stando a quello che abbiamo affermato prima, tuttavia, anche un CSS con media="screen"
potrebbe essere non critico o, più probabilmente, una percentuale più o meno ampia degli stili contenuti in esso potrebbe non essere critica perché non riguardante i contenuti above the fold nella parte alta della pagina.
In questi casi si può analizzare la risorsa ed estrarre i CSS non critici. Possiamo farlo manualmente o avvalendoci di alcuni tool pronti allo scopo. A questo punto si potranno servire i CSS critici per primi e differire (caricare in maniera asincrona e non bloccante) quelli non critici.
Attenzione: non si deve semplicemente differire tutto il contenuto CSS o si incorrerà in sgradevoli fenomeni di FOUC (Flash Of Unstyled Content) in cui l’HTML non stilizzato verrà mostrato per un breve intervallo di tempo (un flash). Solo gli stili non critici sono destinati al caricamento differito.
Nota: il caricamento asincrono di una parte degli stili, da solo, non migliora il tempo complessivo di caricamento della pagina (il codice CSS viene suddiviso e servito con modalità differenti ma il peso in KB rimane invariato), si interviene piuttosto sul First Contentful Paint. In parole semplici mettiamo in condizione il browser di cominciare prima il rendering eliminando un collo di bottiglia ed aumentando la velocità di caricamento percepita.
Caricamento asincrono
Vediamo, in conclusione, come procedere dopo avere estratto i CSS non critici. Gli stili critici verranno serviti all’interno di un tag <style>
nella sezione <head>
della pagina, quelli non critici invece tramite un elemento <link>
in questo modo:
Si tratta di un hack secondo me geniale che sfrutta la capacità del browser di caricare in modo asincrono alcune risorse come detto prima. Questo articolo su Filament Group ne spiega dettagliatamente la logica e, nel seguito del post, fornisce ulteriori e utili delucidazioni in merito. Ne consiglio senz’altro la lettura integrale, qui un estratto.
Per iniziare, l’attributo multimediale del collegamento è impostato su print. Questo è un media type che dice “applica le regole di questo foglio di stile per i media basati sulla stampa” o, in altre parole, applicali quando l’utente cerca di stampare la pagina. Certo, vogliamo che il nostro foglio di stile si applichi a tutti i media (specialmente agli schermi) e non solo alla stampa, ma dichiarando un tipo di media che non corrisponde all’ambiente corrente, possiamo ottenere un effetto interessante e utile: il browser caricherà il foglio di stile senza ritardare il rendering della pagina, in modo asincrono! È utile, ma non è tutto ciò che vogliamo. Vogliamo anche che il CSS si applichi effettivamente all’ambiente screen una volta caricato. Per questo, possiamo utilizzare l’attributo onload per impostare il supporto del collegamento su all quando termina il caricamento.
filamentgroup.com