Core Web Vitals su Next.js nel 2026: come arrivare in verde
Passi concreti per portare LCP sotto 2.5s, INP sotto 200ms e CLS sotto 0.1 su un SaaS Next.js 16, e come leggere il campo quando Lighthouse mente.
Alla fine di questa guida hai un SaaS Next.js 16 che supera i Core Web Vitals al 75esimo percentile dei dati reali: LCP sotto 2.5 secondi, INP sotto 200 millisecondi, CLS sotto 0.1. Non un punteggio Lighthouse in una scheda. Utenti veri su reti vere, misurati dal Chrome User Experience Report sugli ultimi 28 giorni.
La query "core web vitals nextjs guide" produce una valanga di checklist generiche. Questa è specifica per un SaaS Next.js 16 spedito nel 2026, con il React Compiler stabile, il Partial Prerendering pronto per la produzione e INP come metrica di copertina che la maggior parte dei team continua a sbagliare.
Cosa significa "verde" sui Core Web Vitals nel 2026
Tre metriche, ognuna con la sua soglia al 75esimo percentile che Google considera buona:
- LCP (Largest Contentful Paint): sotto 2.5 secondi. Misura quando l'elemento più grande sopra la piega finisce di disegnarsi.
- INP (Interaction to Next Paint): sotto 200 millisecondi. Ha sostituito FID il 12 marzo 2024. Misura la latenza peggiore di tutte le interazioni dell'utente sulla pagina, end to end.
- CLS (Cumulative Layout Shift): sotto 0.1. Misura lo spostamento di layout inatteso nel ciclo di vita della pagina.
Le soglie si applicano al 75esimo percentile degli utenti Chrome reali degli ultimi 28 giorni, segmentati per classe di dispositivo. Una pagina passa solo se tutte e tre le metriche sono in verde. INP è la metrica che oggi più siti continuano a non superare: su mobile, INP segna in media il 35.5% peggio di FID nei confronti pubblicati da Google prima della migrazione, mettendo a nudo interazioni che FID ignorava in silenzio.
L'errore più costoso che vediamo agli onboarding: dare per scontato che un Lighthouse 95 significhi sito in verde. Lighthouse è dato di laboratorio. Google classifica sui dati di campo del CrUX. I due divergono su reti reali, dispositivi reali e sulla coda lunga di interazioni che Lighthouse non simula.
Cosa ti serve prima di iniziare
- Un SaaS Next.js 16 in produzione (App Router, React 19).
- Accesso a PageSpeed Insights e Google Search Console del dominio.
- Un endpoint di Real User Monitoring (RUM). Noi usiamo un endpoint self-hosted che riceve il payload di web-vitals, ma qualunque strumento di analytics che accetti eventi custom va bene.
- Il permesso di mettere in deploy. Le correzioni qui sotto vivono nel tuo codice, non in un setting CDN.
Step 1: Strumenta con useReportWebVitals
Non puoi correggere quello che non misuri in produzione. Lighthouse è la versione laboratorio della domanda. CrUX è la versione pubblica. Il tuo RUM è quella privata, ed è l'unica che fa emergere i problemi abbastanza in fretta da poterci agire sopra.
Aggiungi un client component che collega useReportWebVitals di next/web-vitals e manda ogni metrica al tuo endpoint:
'use client'
import { useReportWebVitals } from 'next/web-vitals'
export function WebVitals() {
useReportWebVitals((metric) => {
fetch('/api/vitals', {
method: 'POST',
body: JSON.stringify(metric),
keepalive: true,
})
})
return null
}Renderizzalo una volta in app/layout.tsx. L'hook scatta per ogni Core Web Vital più FCP e TTFB. Raggruppa il payload per rotta, per classe di dispositivo e per versione del deploy: così, quando una metrica peggiora, sai quale commit ha spedito la regressione.
Step 2: Sistema LCP con preload immagine e dimensioni riservate
Sul SaaS Next.js, l'LCP è quasi sempre un'immagine di una landing, e quasi sempre un hero. Quattro mosse fanno la maggior parte del lavoro:
- Metti
preload={true}sull'immagine LCP. Next.js 16 ha deprecato la proppriorityin favore dipreload, per chiarezza. Il componente emette un<link rel="preload">confetchpriority="high"e nelle misure toglie tra 300 e 800 millisecondi di LCP. Usalo su esattamente un'immagine per pagina: il candidato LCP. - Imposta
widtheheightesplicite (oppurefilldentro un genitore con aspect ratio esplicito). Il componente riserva lo spazio via CSSaspect-ratioed elimina il layout shift che farebbe esplodere il CLS. - Inlinea il CSS critico. Next.js 16 inlinea già il CSS critico per rotta di default. La trappola sono gli import CSS globali che bloccano il render: passa al setaccio
app/layout.tsxe separa tutto ciò che non serve sopra la piega. - Self-hosta i font con
display: swapesize-adjust.next/fontgestisce entrambi. Il descrittoresize-adjustsul fallback impedisce che lo swap del web font crei CLS al caricamento.
Resisti alla tentazione di preloadare tutto. Pre-caricare troppe risorse aggiunge tra 400 e 1200 millisecondi di ritardo, perché il browser si ferma su risorse che non sono sul percorso critico. Un hero, non cinque.
Step 3: Sistema INP con React Compiler, RSC e task spezzati
INP misura la latenza peggiore di interazione, end to end: input delay, runtime dell'event handler e il paint che segue. Una pagina con un solo click lento ogni cento interazioni può non passare INP. I rimedi sono architetturali, non cosmetici:
- Abilita il React Compiler. Stabile in Next.js 16, lo attivi con
experimental.reactCompiler: trueinnext.config.ts. Memorizza i componenti in automatico e toglie una classe di re-render ridondanti senza chiamate manuali auseMemoomemo(). Il guadagno è costante: ogni interazione fa meno lavoro, il che comprime la coda lunga su cui INP premia. - Sposta lavoro client sui Server Components. I team che adottano RSC in modo completo riportano riduzioni dal 50 al 70 percento del JavaScript di primo caricamento. Meno JavaScript client significa meno parse, meno hydration, meno contesa sul main thread durante le interazioni.
- Spezza i task lunghi. Qualunque handler che fa più di 50 ms di lavoro blocca il paint successivo. Cedi il controllo con
scheduler.yield()quando disponibile, altrimenti conawait new Promise(requestAnimationFrame). Sposta il lavoro fuori dal path del click dentrostartTransitionquando non deve bloccare la risposta visiva. - Passa al setaccio gli event handler. Il pannello Performance di Chrome DevTools segnala le interazioni lente in tracce equivalenti al campo. La guida web.dev su come trovare le interazioni lente nel campo è il riferimento.
Il trade-off onesto: il React Compiler può occasionalmente over-memoizzare, tenendo valori in memoria più a lungo di quanto il tuo codice intendeva. Profila dopo averlo abilitato. I casi in cui peggiora le cose sono rari e identificabili.
Step 4: Sistema CLS con dimensioni esplicite e disciplina sui fallback PPR
Il CLS sembra facile, non lo è. Le vittorie veloci:
- Ogni immagine, video, iframe e slot pubblicitario ha
widtheheightesplicite, oppure un genitore conaspect-ratio. Senza eccezioni. - Riserva lo spazio per il contenuto renderizzato lato client. Skeleton loader con le stesse dimensioni del contenuto finale. Se la card finale è 320x180, lo skeleton è 320x180.
- Fallback dei font calibrati con
size-adjust. Il setup di default dinext/fontlo fa, ma i setup di font custom regrediscono spesso.
La trappola del 2026: il Partial Prerendering, stabile in Next.js 16, introduce un nuovo rischio di CLS. Quando un fallback di Suspense dentro uno shell PPR viene rimpiazzato dal contenuto reale, se le dimensioni differiscono, la pagina si sposta. È peggio di un layout shift su SSR completo perché l'utente ha già visto un layout finito. La cura: ogni fallback di Suspense ha le stesse dimensioni del contenuto che sostituisce.
Step 5: Verifica sui dati di campo CrUX, non su Lighthouse
Spedisci le correzioni. Aspetta 28 giorni. Poi guarda CrUX.
PageSpeed Insights mostra campo e laboratorio uno accanto all'altro. La sezione campo è quella che conta per il ranking e rappresenta i tuoi utenti. La sezione laboratorio serve a fare debugging. Se il campo è rosso e il laboratorio verde, il divario è su una rete più lenta, su un dispositivo più lento o su un'interazione di coda che non stai testando.
Per un feedback più veloce della finestra CrUX da 28 giorni: il tuo RUM. Imposta un alert quando l'INP p75 sui 7 giorni mobili supera i 200 ms su una rotta ad alto traffico. Ti dà 21 giorni di vantaggio sul momento in cui Google se ne accorgerebbe.
Errori comuni e come correggerli
- Lighthouse verde, CrUX rosso. La tua macchina di test è troppo veloce. Strozza a Slow 4G più 4x CPU in DevTools e rilancia. Testa su un dispositivo Android di fascia media reale, non solo sul tuo laptop.
- LCP verde su desktop, rosso su mobile. Tipico. Il mobile scarica lo stesso payload su una rete peggiore. Audit del peso delle immagini, dei font e di qualsiasi script di terze parti che blocchi il render.
- INP è salito dopo aver abilitato il React Compiler. Qualcosa nell'albero re-renderizza di più, non di meno. Profila con i React DevTools e trova la prop o il context instabile che annulla la memoizzazione.
- CLS schizza dopo un rollout PPR. Uno dei tuoi fallback di Suspense non ha le stesse dimensioni del contenuto reale. Diff layout per layout fra fallback e contenuto finale.
Andare oltre
Sui Core Web Vitals di Next.js 16 il verde è il pavimento, non il soffitto. Due letture vicine valgono il tuo tempo quando il pavimento è a posto: la nostra analisi di cosa cambia in Next.js 16 e React 19 per i nuovi progetti SaaS e la nostra posizione su se ha ancora senso memoizzare a mano dopo l'arrivo del compilatore.
Domande frequenti
- Quanto tempo richiede sistemare i Core Web Vitals su un SaaS Next.js?
- Da una a quattro settimane di lavoro focalizzato per un SaaS piccolo, di più se hai molte pagine marketing con media hero pesanti e una coda lunga di interattività client. La strumentazione dello Step 1 si fa in un giorno. Le correzioni di LCP e CLS sono di solito da due a cinque giorni. Il lavoro su INP è quello aperto, perché dipende da quanto JavaScript client spedisci oggi. I dati di campo confermano il risultato 28 giorni dopo il deploy.
- Un Lighthouse verde significa che passo i Core Web Vitals?
- No. Lighthouse gira in un ambiente controllato con dispositivo e rete sintetici. Google classifica sui dati del Chrome User Experience Report, che aggrega utenti reali sugli ultimi 28 giorni al 75esimo percentile. Un Lighthouse 95 con un CrUX rosso è la norma quando i tuoi utenti reali sono su reti più lente, dispositivi più vecchi o pattern di interazione che Lighthouse non simula.
- Si può attivare il React Compiler in produzione su un SaaS Next.js 16?
- È stabile da Next.js 16. La maggior parte dei componenti beneficia della memoizzazione automatica senza modifiche al codice. I casi limite dove peggiora sono componenti con closure annidate instabili o librerie di terze parti che mutano i riferimenti a ogni render. Abilitalo, profila per una settimana un campione di rotte con tante interazioni e tieni d'occhio INP. Se una rotta peggiora togli il flag, raccogli il caso e correggi il pattern a monte.
- I Server Components migliorano direttamente INP?
- Indirettamente. I Server Components renderizzano sul server e streamano HTML, quindi il browser parsa, idrata ed esegue meno JavaScript. Meno lavoro client significa più spazio sul main thread quando l'utente interagisce. I killer diretti di INP sono gli event handler lenti e i task lunghi al caricamento. I Server Components rimuovono in parte i secondi ma non sistemano un click handler da 300 ms.
Studio
Inizia un progetto.
Un partner unico per il prodotto digitale che devi costruire. Produzione più veloce, tecnologie moderne, costi ridotti. Un team, una fattura.