Una guida ai Core Web Vitals per la priorizzazione delle risorse
Non lasciare che il browser tiri a indovinare. Obbligalo a caricare ciò che conta quando conta!

Guida ai Core Web Vitals per la priorizzazione delle risorse
Il motore di priorizzazione predefinito del browser funziona in base a euristiche (ipotesi imperfette basate sui tipi di file e sulla posizione nel documento). Le risorse vengono messe in coda nel momento in cui vengono scoperte dal preload scanner o dal parser DOM.

Ciò può diventare un problema se si considera che la larghezza di banda della rete e la CPU non sono risorse illimitate. Ad esempio: ogni byte trasferito per uno script di tracciamento a bassa priorità, se scaricato contemporaneamente, compete direttamente con i byte necessari per il tuo Largest Contentful Paint (LCP).
Ora, non è colpa del browser: nell'HTML del nostro esempio, il browser non aveva modo di sapere di aver assegnato la priorità agli asset sbagliati, ritardando il rendering critico.
Sei tu a sapere cosa è importante e controlli questa programmazione attraverso due meccanismi: Priorizzazione (potenziamento dei segnali critici) e Depriorizzazione (programmazione delle risorse non critiche in un momento in cui sono meno invadenti).
Table of Contents!
Limiti delle euristiche del browser
I browser assegnano la priorità in base a un punteggio di "priorità calcolata". Questo punteggio deriva dal tipo di risorsa (CSS, Script, Immagine) e dalla sua posizione nell'HTML/DOM. Sebbene sia generalmente efficace per documenti semplici, questo sistema fallisce quando le risorse non vengono riconosciute tempestivamente (dal preload scanner) o vengono attivate le risorse sbagliate per un download anticipato.
Il limite del Preload Scanner
Per accelerare la scoperta, i browser utilizzano un "preload scanner", un parser leggero che anticipa il parser HTML principale per trovare gli URL delle risorse. Questo scanner ha dei limiti (che lo rendono veloce ed efficace): analizza solo l'HTML. Non può vedere all'interno dei file CSS, non esegue JavaScript e non effettua il rendering (quindi non può "vedere se le risorse sono visibili nel viewport").
Di conseguenza, qualsiasi risorsa referenziata in un foglio di stile (come un'immagine di sfondo o un web font), iniettata da uno script o caricata in modalità lazy, viene saltata o nemmeno vista finché il parser principale non scarica ed elabora l'intera pagina web. Ciò crea un "ritardo di scoperta", in cui il browser è di fatto ignaro dell'esistenza di risorse critiche.
Contesa delle risorse
Quando il browser scopre le risorse, spesso tenta di scaricarle simultaneamente con altre richieste in sospeso. Se un'importante immagine LCP compete con uno script a media priorità o con immagini non importanti (come le icone dei social media nel footer), si dividono la larghezza di banda disponibile. Questa contesa prolunga i tempi di caricamento per entrambi, spingendo la metrica LCP nella zona "Needs Improvement".
Strategie di priorizzazione manuale
Per costruire un percorso di rendering veloce, devi intervenire manualmente. L'obiettivo è massimizzare la larghezza di banda per l'LCP e minimizzarla per tutto il resto.
1. Correggere la scoperta con il preloading
Devi esporre manualmente le risorse nascoste al preload scanner. Spostando le risorse critiche nell'HTML <head> usando rel="preload", costringi il browser a riconoscerle immediatamente, eliminando il ritardo di scoperta.
L'implementazione:
<!-- Esponi il font allo scanner immediatamente -->
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin>
<!-- Esponi l'immagine di sfondo LCP immediatamente -->
<link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high"> 2. Sovrascrivere le euristiche LCP
I browser spesso assegnano la priorità "Bassa" o "Media" alle immagini perché non conoscono le dimensioni del layout finale durante il fetch iniziale. Il browser non può determinare se un'immagine è l'LCP fino a quando non viene costruito il render tree, il che è troppo tardi.
L'implementazione:
Forza lo stato di priorità "Alta" sull'elemento LCP usando fetchpriority="high". Questo aggira le euristiche interne e mette l'immagine in cima alla coda di download.
<!-- Forza il fetch immediato ad alta priorità -->
<img src="hero.jpg" alt="Prodotto Hero" fetchpriority="high"> 3. Deprioritizzare le immagini non importanti
Liberare la larghezza di banda è spesso più efficace che aumentare la priorità. Devi posticipare esplicitamente le risorse non essenziali per liberare il canale di rete per le risorse critiche.
L'implementazione:
- Below-the-fold: Usa loading="lazy" per posticipare il download finché l'utente non scorre la pagina.
- Above-the-fold Secondarie: Usa fetchpriority="low" per le slide dei caroselli o per gli elementi visivi secondari che vengono renderizzati inizialmente ma che sono meno importanti dell'LCP.
- Above-the-fold e visivamente non importanti: Ignora il preload scanner usando loading="lazy" e assegna una bassa larghezza di banda. Utile per quelle piccole immagini come bandiere o icone che non catturano mai l'attenzione durante il primo render ma che potrebbero innescare molte richieste iniziali di larghezza di banda.
<!-- Immagine LCP: Massima priorità -->
<img src="slide-1.jpg" fetchpriority="high">
<!-- Immagine secondaria del carosello: fetch immediato, basso utilizzo della larghezza di banda -->
<img src="slide-2.jpg" fetchpriority="low">
<!-- Bandiere di traduzione: mentre sono nel viewport, nascondile dal preload scanner -->
<img src="dutch-flag.jpg" loading="lazy" fetchpriority="low">
<!-- Immagine fuori schermo: fetch differito -->
<img src="footer-promo.jpg" loading="lazy"> 4. Controllare l'esecuzione degli Script
JavaScript blocca il parser DOM. Se si usano i tag <script> standard, il browser interrompe l'analisi HTML per scaricare ed eseguire il file.
L'implementazione:
- defer: Usalo per la logica dell'applicazione. Viene scaricato in parallelo (bassa priorità) ed eseguito solo dopo che l'HTML è stato completamente analizzato, preservando l'ordine delle dipendenze.
- async: Usalo per script di terze parti indipendenti (come analytics). Viene scaricato in parallelo ed eseguito immediatamente al completamento, ignorando l'ordine.
- Inject: Aggira il preload scanner in modo da non competere con la larghezza di banda iniziale. Gli script iniettati vengono trattati come async.
- Schedule + Inject: Inietta gli script in un momento successivo, ad esempio quando è stato attivato l'evento load.
<!-- Logica dell'applicazione: Non bloccante, preserva l'ordine di esecuzione -->
<script src="app.js" defer></script>
<!-- Consenso di terze parti: Non bloccante, esecuzione indipendente -->
<script src="consent.js" async></script>
<script>
/* Esempio di iniezione analytics */
const script = document.createElement('script');
script.src = 'analytics.js';
script.async = true;
document.head.appendChild(script);
/* Esempio iniezione + programmazione per la chat */
window.addEventListener('load', () => {
const chatScript = document.createElement('script');
chatScript.src = 'chat-widget.js';
document.head.appendChild(chatScript); });
</script>5. Sbloccare il rendering CSS
Il CSS blocca il rendering per sua natura: il browser non sa quale sia l'aspetto della pagina senza CSS. Quindi scarica e analizza prima i fogli di stile.
Strategie di ottimizzazione:
- Evitare @import: Crea catene di dipendenze sequenziali che devastano le prestazioni.
- Ottimizzare le dimensioni del bundle: Evita file CSS più piccoli di 3kB (overhead) e più grandi di 20kB (bloccanti). Idealmente, punta a file di ~15kB.
- Caricamento asincrono: Carica gli stili off-screen in modo asincrono per sbloccare il percorso critico.
- Compromesso del Critical CSS: Sebbene l'inserimento in linea del Critical CSS migliori la prima visualizzazione di pagina, aggira la cache del browser, il che può ritardare le visualizzazioni di pagina successive.
L'implementazione:
Elimina del tutto @import. Usa i tag <link> per il caricamento parallelo. Per il CSS non critico (come gli stili di stampa), usa l'attributo media per sbloccare il thread principale.
<!-- Critical CSS: Blocca il rendering (Corretto) -->
<link rel="stylesheet" href="main.css">
<!-- CSS per la stampa: Non bloccante fino al verificarsi dell'evento di stampa -->
<link rel="stylesheet" href="print.css" media="print">
<!-- Pattern asincrono: Si carica a bassa priorità, si applica al caricamento (load) -->
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'"> 6. Stabilizzare il rendering dei font
I font sono risorse bloccanti pesanti. Una priorizzazione efficace richiede limiti rigorosi su ciò che viene scaricato e il controllo su come viene renderizzato.
Strategie di ottimizzazione:
- Limiti rigidi di preload: Fai il preload solo dei 1-2 file di font più importanti (di solito il testo LCP). Il preload di oltre 5 font intasa la larghezza di banda.
- Ridurre il payload: Usa i Variable Fonts (un file per tutti i pesi) e il Subsetting (rimozione dei caratteri non utilizzati) per ridurre al minimo le dimensioni del file.
- Strategia di rendering:
- Usa
swapper un rendering veloce (evita il FOIT/testo invisibile). - Usa
optionalper prevenire il CLS (evita layout shift su reti lente).
- Usa
L'implementazione:
<!-- Fai il preload SOLO del sottoinsieme critico (es. Intestazione + Corpo) -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter Variable';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
/* Scegli in base ai requisiti di stabilità: */
font-display: optional; /* Nessun layout shift, ma il font potrebbe rimanere quello di fallback */
/* font-display: swap; Visibilità del testo più rapida, ma rischia il layout shift */
}
</style> Your Lighthouse score is not the full picture.
Lab tests run on fast hardware with a stable connection. I analyze what your actual visitors experience on real devices and real networks.
Analyze Field Data
