Risorse che bloccano il rendering: che cosa blocca davvero, e perché async non è la soluzione

  • vuetelemetry
  • Guide
  • 8 min di lettura

Lighthouse nomina l'audit ed elenca i file. Non spiega che uno script senza attributo ferma di colpo il parser, che async blocca comunque il rendering quando viene eseguito, e che il CSS blocca per un motivo del tutto diverso.

«Eliminare le risorse che bloccano il rendering» è l'audit più frequente di un report Lighthouse, e il meno spiegato. Nomina i file e si ferma lì. Dietro quell'unica riga si nascondono due meccanismi diversi, che richiedono correzioni diverse.

Gli script: che cosa fa davvero ogni attributo

Persone in coda lungo un cordolo, viste dall'alto, con segnaletica orizzontale sull'asfalto accanto. Uno script che blocca fa lo stesso al parser: tutto ciò che sta dietro aspetta, in ordine, che quello davanti abbia finito.
Persone in coda lungo un cordolo, viste dall'alto, con segnaletica orizzontale sull'asfalto accanto. Uno script che blocca fa lo stesso al parser: tutto ciò che sta dietro aspetta, in ordine, che quello davanti abbia finito.

**Uno script classico senza attributo ferma il parser.** MDN lo dice senza giri di parole: gli script senza `async`, `defer` o `type="module"` vengono *«recuperati ed eseguiti immediatamente, prima che il browser continui ad analizzare la pagina»*. Il browser sta costruendo il documento, incontra il tag e si ferma: scaricare, eseguire, poi riprendere. Tutto ciò che sta sotto aspetta.

**`defer` è la risposta nella maggior parte dei casi.** L'attributo indica che lo script *«deve essere eseguito dopo l'analisi del documento, ma prima dell'evento DOMContentLoaded»*. L'analisi prosegue senza interruzioni, e gli script differiti *«vengono eseguiti nell'ordine in cui appaiono nel documento»*: uno script che dipende da un altro lo ottiene comunque.

**`async` è quello che si usa male.** Viene recuperato *«in parallelo all'analisi e valutato non appena è disponibile»*, il che suona strettamente migliore. Quel che si omette è la frase subito dopo: *«una volta completato il download, lo script viene eseguito, il che impedisce alla pagina di essere renderizzata»*.

Async elimina dunque il blocco durante il **download**, non durante l'**esecuzione**. Uno script grande caricato con async arriva quando arriva, in mezzo all'analisi, e blocca il rendering in quel momento. E poiché l'ordine di esecuzione segue quello di arrivo, MDN avverte che non c'è *«alcuna garanzia che gli script vengano eseguiti in un ordine preciso»*, il che rompe tutto ciò che ha dipendenze.

La regola breve: **defer per i propri script, async solo per terze parti davvero indipendenti**, come un beacon di analytics che non parla con nessuno.

Il CSS blocca per un altro motivo

**Il CSS blocca per un altro motivo, e la correzione non è un attributo.** Un foglio di stile non ferma il parser HTML, ma il browser non disegnerà finché non ha il CSS che gli serve, perché disegnare prima e ristilizzare poi mostrerebbe un lampo di contenuto non stilizzato. È un blocco del rendering, non dell'analisi.

  • Senza attributo: recuperato ed eseguito subito, l'analisi si ferma
  • defer: esegue dopo l'analisi, nell'ordine del documento, prima di DOMContentLoaded
  • async: nessun blocco al download, ma l'esecuzione blocca il rendering, e l'ordine non è garantito
  • CSS: non blocca l'analisi, blocca il disegno - limitane l'ambito con media
  • I tag di terze parti sono spesso la quota maggiore dell'audit

Qui la leva è l'ambito, non il momento. Un foglio che si applica a un solo contesto può portare un attributo `media`, e il browser lo recupererà senza lasciargli bloccare il primo disegno - `media="print"` è il caso noto. Resta il CSS di cui la prima schermata ha davvero bisogno, ed è quello che conviene tenere piccolo.

Qui la leva è l'ambito, non il momento. Un foglio che si applica a un solo contesto può portare un attributo `media`, e il browser lo recupererà senza lasciargli bloccare il primo disegno - `media="print"` è il caso noto. Resta il CSS di cui la prima schermata ha davvero bisogno, ed è quello che conviene tenere piccolo.

- vuetelemetry

Dove sta il peso, e come confermarlo

**I tag di terze parti sono di solito il peso reale.** Il tuo bundle è sotto i tuoi occhi e finisce ottimizzato; il tag manager, il widget di chat e il banner di consenso arrivano come script che non hai scritto, spesso caricandone altri a loro volta. Verificare quanto costano davvero - e se ciascuno se lo merita - sposta il numero molto più che limare kilobyte dal proprio codice.

**E poi misura sul campo, non sul report.** Lighthouse ti dice che una risorsa bloccava il rendering; non ti dice se rimuoverla ha cambiato qualcosa per i tuoi visitatori. Quella differenza tra un audit di laboratorio e utenti reali è [un argomento a sé](/it/articles/dati-sul-campo-vs-dati-di-laboratorio), ed è quella che decide se il lavoro è valso la pena.

FAQ

Che cosa significa «eliminare le risorse che bloccano il rendering»?

È un audit di Lighthouse che elenca script e fogli di stile che ritardano il primo disegno. Dietro ci sono due meccanismi diversi: uno script classico senza attributo ferma del tutto il parser HTML, mentre un foglio di stile lascia proseguire l'analisi ma impedisce il disegno finché non è caricato. Richiedono correzioni diverse, ed è per questo che l'audit da solo non basta per agire.

Devo usare async o defer?

defer per i propri script, async solo per terze parti davvero indipendenti. defer esegue dopo l'analisi, nell'ordine del documento, quindi le dipendenze continuano a funzionare. async esegue appena il download è completo, il che blocca il rendering in quell'istante, e MDN avverte che non c'è garanzia sull'ordine di esecuzione.

async rende uno script non bloccante?

Non del tutto, ed è il fraintendimento comune. async elimina il blocco durante il download: lo script viene recuperato in parallelo all'analisi. Ma MDN indica che, completato il download, lo script viene eseguito e quell'esecuzione impedisce alla pagina di essere renderizzata. Uno script async grande blocca semplicemente in un momento imprevedibile anziché prevedibile.

Perché il CSS blocca il rendering?

Perché disegnare prima che arrivi il foglio di stile mostrerebbe contenuto non stilizzato, da rifare subito dopo. Quindi il browser aspetta. A differenza di uno script, il CSS non ferma il parser HTML: ferma il disegno. La correzione non è un attributo ma l'ambito - un foglio limitato da un attributo media viene recuperato senza trattenere il primo disegno.

Come faccio a sapere se la correzione è servita?

Non dal report di Lighthouse, che ti dice solo che una risorsa bloccava il rendering. Se il cambiamento ha raggiunto i tuoi visitatori si vede nei dati sul campo, al 75° percentile su 28 giorni. Un audit di laboratorio individua il candidato; solo il campo conferma il risultato.

Stack correlato