Network dependency tree in Lighthouse: come leggerlo e risolverlo
I file che il browser trova solo dentro altri file costringono la pagina ad attenderli uno dopo l'altro. Come leggere l'albero e le tabelle del preconnect, e come accorciare le catene.
Cos'è il Network dependency tree in PageSpeed Insights?
Il Network dependency tree in Lighthouse ("Avoid chaining critical requests" prima di Lighthouse 13) mostra i file di cui la pagina ha bisogno per primi e quale file ciascuno ha dovuto attendere: ogni file trovato dentro un altro file aggiunge un'attesa. Ospita i font sul tuo dominio, collega i fogli di stile nell'HTML invece di usare @import e usa il preconnect solo quando un file critico proviene da un dominio che non puoi evitare.
Vuoi la soluzione rapida? Salta a web font, @import in WordPress, Shopify o file aggiunti da uno script.
Come si legge il Network dependency tree?
Lighthouse 13 e PageSpeed Insights descrivono l'avviso così: "Avoid chaining critical requests by reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load". Ha sostituito "Avoid chaining critical requests" (in precedenza "Minimize critical requests depth") e "Preconnect to required origins", ed è per questo che sotto l'albero compaiono due tabelle dedicate al preconnect.
Il report qui sotto proviene dalla home page di uno studio dentistico che ho impostato come un sito WordPress: il foglio di stile del child theme importa quello del tema genitore, che a sua volta importa Google Fonts, e le icone arrivano da Font Awesome su una CDN.

Lighthouse 13.6 su mobile, throttling di DevTools (Slow 4G, CPU 4x).
- Una riga rientrata indica un file che il browser ha trovato solo all'interno del file al livello superiore, e che quindi ha dovuto attendere. Le righe allo stesso livello si scaricano in parallelo, come i tre file di font sotto il foglio di stile css2 di Google.
- Il tempo e i KiB su una riga: quando il file è arrivato, a partire dall'inizio del caricamento della pagina, e la sua dimensione.
- Maximum critical path latency è il tempo della catena più lenta, in arancione. Nella pagina dello studio dentistico è il font di icone da 155 KiB a due livelli di profondità: arriva dopo i font di Google quattro livelli più sotto.
- LCP e Unscored: l'avviso non ha peso nel punteggio Performance, ma i suoi fogli di stile ritardano il first paint, e il LCP non può mai avvenire prima.
PageSpeed Insights registra il caricamento senza throttling: il suo albero mostra tempi molto più brevi rispetto a questo screenshot.
Perché una catena di file ritarda la pagina?
Nella pagina dello studio dentistico, il visitatore vede prima una schermata bianca, poi il testo con un font di fallback che cambia all'arrivo dei web font, con cerchi vuoti al posto delle icone.
Il browser scansiona l'HTML in anticipo (il preload scanner) e richiede subito tutti i file che trova. Trova un file indicato dentro un altro file solo dopo che quest'ultimo è arrivato: un font in un foglio di stile, un foglio di stile dietro un @import, uno script aggiunto da uno script. Ogni livello aggiunge un round trip verso il server prima che la richiesta successiva possa partire.
Un file su un altro dominio aspetta ancora di più: il browser deve prima aprire una connessione (DNS, TCP e TLS), operazione che su rete mobile richiede varie volte il tempo di una richiesta su una connessione già aperta. Nella pagina dello studio dentistico i font di Google si trovano quattro livelli sotto l'HTML, dietro due @import, gli ultimi due su nuovi domini (fonts.googleapis.com, fonts.gstatic.com). Render-blocking requests spiega perché un foglio di stile blocca il first paint.
Quanto è più veloce la pagina con un albero piatto?
Dopo il fix, la pagina dello studio dentistico esegue il paint un secondo prima e mostra i propri font quasi due secondi prima. Ho misurato tre versioni. Prima contiene i due @import. Link ha gli stessi file collegati nell'HTML, come li stampa WordPress con wp_enqueue_style. Dopo unisce i fogli di stile genitore e child in un unico file, ha i font sul dominio del sito, tutti e tre con preload, e le icone come SVG inline.
| Prima | Link | Dopo | |
|---|---|---|---|
| Livelli | 4 | 2 | 1 |
| Catena più lenta | 4,18 | 3,25 | 1,21 |
| First paint | 2,36 | 1,43 | 1,35 |
| Tutti i font | 3,57 | 2,61 | 1,72 |
| LCP | 2,36 | 1,73 | 1,96 |
Tempi in secondi, su uno smartphone con throttling (Slow 4G, CPU 4x più lenta). Livelli e catena più lenta (Maximum critical path latency nel report) ricavati da Lighthouse 13.6 con lo stesso throttling.

Prima

Dopo
A due secondi dall'inizio del caricamento sullo stesso smartphone con throttling.
Link offre già gran parte del guadagno sul first paint, perché i due livelli di @import sono spariti, mentre font e icone attendono ancora i rispettivi domini. Il LCP, la foto hero, arriva 0,4 s prima dopo il fix. Link registra il LCP più anticipato perché la foto ha la banda quasi interamente per sé; in Dopo i tre font con preload la condividono, quindi il fix ne precarica solo uno o due.
Per verificare se i visitatori reali attendono la catena, suddividi il LCP su mobile nelle sue fasi in CoreDash: fogli di stile e font in ritardo emergono come un lungo render delay, l'attesa successiva all'arrivo dell'immagine LCP o, per il testo, del primo byte.

CoreDash su mobile, p75, testo come elemento LCP: confronta il Render Delay con il Time To First Byte.
Cosa significano Preconnected origins e Preconnect candidates?
Un preconnect (<link rel="preconnect">) apre la connessione verso un dominio prima che il browser debba richiedere un file da lì. Preconnected origins elenca i domini verso cui la pagina effettua il preconnect; Preconnect candidates elenca i domini i cui file hanno comunque dovuto stabilire una connessione, con il tempo che un preconnect potrebbe risparmiare (Est LCP savings).

La stessa pagina dello studio dentistico con una grande foto hero in lazy loading, Lighthouse 13.6 con throttling di DevTools.
- "Unused preconnect. Only use preconnect for origins that the page is likely to request." La pagina non ha caricato nulla da quel dominio, in questo caso maps.googleapis.com e www.youtube.com. Rimuovilo dopo aver verificato che nessun altro template, come il checkout, lo utilizzi.
- "Unused preconnect. Check that the crossorigin attribute is used properly." Un font richiede una connessione aperta con
crossorigin, mentre un foglio di stile o uno script ne richiede una senza. cdnjs.cloudflare.com invia alla pagina dello studio dentistico il foglio di stile di Font Awesome e il relativo font, quindi il foglio di stile ha sfruttato il preconnect e il font ha aperto una seconda connessione. Ospita il font sul tuo dominio; solo quando non puoi, aggiungi un secondo preconnect verso quel dominio concrossorigin. - "More than 4 preconnect connections were found." Ogni preconnect apre una connessione insieme ai file di cui la pagina ha bisogno per primi. Ospita ciò che puoi sul tuo dominio e riserva il preconnect solo a un file critico su un dominio che non puoi evitare.
- Un dominio sotto Preconnect candidates. Sposta quel file sul tuo dominio; se non puoi e il file è critico, usa il preconnect.
Se non puoi ancora ospitare Google Fonts sul tuo dominio, collega il foglio di stile nell'HTML e imposta il preconnect verso fonts.gstatic.com con crossorigin; il browser si connette a fonts.googleapis.com non appena legge il link. Rimane comunque una catena.
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> Le impostazioni di preconnect dei plugin non gestiscono sempre crossorigin nel modo corretto: DNS Preconnect di LiteSpeed Cache non lo inserisce su nessun dominio, e Perfmatters lo applica solo se spunti la relativa casella. Controlla il sorgente della pagina: solo i domini dei font ne hanno bisogno.
Come si risolve il Network dependency tree?
Parti dalla catena più lenta, quella contrassegnata in arancione da Lighthouse, dalla riga più profonda. Per ogni file chiediti: può essere richiamato nell'HTML o provenire dal tuo dominio?
Google Fonts e altri web font
Senza scrivere codice, attiva l'opzione per ospitare Google Fonts sul tuo dominio: Self-host Google Fonts in WP Rocket o FlyingPress, Local Google Fonts in Perfmatters, Load Google Fonts Locally in Elementor (Settings, Performance), o il plugin OMGF. L'impostazione di WP Rocket non rileva un @import di Google Fonts nel foglio di stile del tema: se dopo l'operazione fonts.googleapis.com è ancora nell'albero, rimuovi l'@import (sezione seguente). Un'opzione che carica Google Fonts in modo "asincrono" con uno script font loader, come in LiteSpeed Cache e Autoptimize, aggiunge un livello alla catena: ospita invece i font sul tuo dominio.
Se procedi a mano, inserisci le regole @font-face nel tuo foglio di stile, con i file woff2 in una cartella fonts accanto:
@font-face {
font-family: "Poppins";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("fonts/poppins-v24-latin-700.woff2") format("woff2");
} Un font può essere dichiarato solo dentro un foglio di stile, quindi solo un preload accorcia questa catena. Usa meno file di font, poi precaricane uno o due, partendo da quello del testo più grande nella prima schermata, e verifica il LCP subito dopo:
<link rel="preload" href="/wp-content/themes/acme-smile/fonts/poppins-v24-latin-700.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/wp-content/themes/acme-smile/fonts/open-sans-v44-latin.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/wp-content/themes/acme-smile/style.css?ver=2.5.0"> Il preload richiede crossorigin, anche sul tuo dominio, altrimenti il font viene scaricato due volte. Font display spiega il preload dei font.
In Next.js, next/font ospita e precarica già i font: sostituisci un @import url(https://fonts.googleapis.com/...) manuale in un file CSS con next/font.
Temi WordPress con @import
Un @import di Google Fonts eliminato dal tema genitore ricompare con il successivo aggiornamento: cerca un'impostazione per i font nel tema, oppure chiedi allo sviluppatore di caricare i font con enqueue.
Un @import del foglio di stile genitore nello style.css di un child theme aggiunge un livello. Chiedi all'autore del tema un child theme che non lo utilizzi, oppure invia a uno sviluppatore l'albero del report e questo codice per il file functions.php del child theme, che sostituisce l'@import:
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
} ); Controlla poi il sorgente della pagina: il foglio di stile del tema genitore deve caricarsi una sola volta.
Font di icone
Font Awesome e le icone di Elementor caricano un foglio di stile che carica un font contenente tutte le icone. In Elementor attiva Inline Font Icons: sostituisce il foglio di stile e il font con SVG inline. Altrove, sostituisci le icone usate dalla pagina con SVG inline, oppure ospita Font Awesome sul tuo dominio.
Shopify
Seleziona i font nell'editor del tema (Theme settings, Typography) invece di incollare il codice di Google Fonts in theme.liquid: in questo modo il tema li distribuisce dal dominio del negozio, mentre Dawn e i temi derivati li precaricano. Gli app embed che aggiungono un foglio di stile compaiono nell'albero: disattivali uno alla volta ed esegui di nuovo Lighthouse. Shopify invia i propri preconnect negli header della pagina, verso la propria CDN e verso i primi tre domini esterni da cui arrivano i file bloccanti, e Lighthouse li conta nel limite di quattro. Rimuovi da theme.liquid un vecchio preconnect a cdn.shopify.com e aggiungi il tuo solo per un dominio che serve ancora all'albero; ogni app embed disattivato può rimuovere uno di quelli di Shopify. Se "More than 4 preconnect connections" resta anche quando rimangono solo quelli di Shopify, lascialo stare.
File aggiunti da uno script e servizi che non puoi modificare
Un foglio di stile aggiunto da uno script deve attendere quello script: se serve alla prima schermata, inserisci il relativo link nell'HTML; altrimenti, differisci lo script. Uno strumento di consenso che deve partire per primo rimane bloccante; se carica file da un secondo dominio che non puoi evitare, imposta il preconnect verso quel dominio. Quando il server impiega tempo a generare l'HTML, 103 Early Hints invia il preconnect e il preload dei font prima dell'HTML stesso.
Perché l'albero è ancora rosso dopo il fix?
Lighthouse segna l'avviso in rosso non appena l'HTML carica un foglio di stile, quindi una pagina priva di catene resta rossa. È il rosso che puoi tenere: l'HTML e i file che richiama direttamente. Ogni riga rientrata sotto un altro file è una catena da eliminare:
- Font sotto il tuo foglio di stile. Usa meno file e precaricane uno o due. Un font non visibile nella prima schermata è l'unica catena che può rimanere.
- File aggiunti da un servizio. La funzione Email Obfuscation di Cloudflare (
email-decode.min.js) e il beacon di Web Analytics, oppureguest.vary.phpdella Guest Mode di LiteSpeed Cache. Disattiva la funzionalità.
Un bug noto di PageSpeed Insights inserisce a volte nell'albero richieste appartenenti ad altri siti: ripeti il test.

La pagina dello studio dentistico senza più alcuna catena, Lighthouse 13.6 con throttling di DevTools.
Come si verifica che l'albero si sia accorciato?
Esegui di nuovo Lighthouse e confronta prima i livelli e la catena più lenta, dato che il valore di Maximum critical path latency varia leggermente da un test all'altro. La colonna Initiator nel pannello Network di Chrome DevTools mostra quale file ha richiesto ciascun file. Per i visitatori reali, monitora FCP e LCP su mobile in CoreDash a partire dalle visite successive; Search Console impiega fino a 28 giorni.
La catena più lunga deriva da un tema o un page builder che non puoi modificare, oppure da un'app che carica i propri font? In una Core Web Vitals power hour analizziamo insieme l'albero, file per file, e stabiliamo quali file spostare sul tuo dominio, quali inserire nell'HTML e quale dominio richiede ancora un preconnect.

Ti serve un sito più veloce?
Sono Arjen e da 17 anni sistemo siti lenti. Se hai problemi che non riesci a risolvere da solo, mandami il tuo URL e ne parliamo.
Mandami il tuo URL
Perché il fix non funziona?
A volte la CDN serve ancora il vecchio HTML, oppure il fix è finito nel template desktop e il mobile ne usa un altro. Mandami il tuo URL e il problema, e ti rispondo con qualche orario. Prima analizzo i tuoi field data, poi dedichiamo un'ora al tuo sito, ed entro un giorno hai le mie note per iscritto. 350 € IVA esclusa.
Mandami il tuo URLNon hai uno sviluppatore per il fix? Faccio io il lavoro, su una copia del tuo sito.