Browser reflow: cosa lo scatena e come influisce sui Core Web Vitals
Il reflow ricalcola le posizioni degli elementi e blocca il main thread. Scopri cosa lo scatena, come rilevarlo e come prevenirlo.

Cos'è il browser reflow?
Il reflow è ciò che accade quando il browser ricalcola la posizione e la dimensione degli elementi sulla pagina. Ogni volta che modifichi il DOM o una proprietà CSS che influisce sul layout, il browser deve capire di nuovo dove posizionare ogni cosa. Questo calcolo blocca il main thread. Non succede nient'altro finché non finisce.
Un singolo reflow su una pagina semplice richiede microsecondi. Ma scatenane centinaia durante un'interazione dell'utente e ti ritroverai con centinaia di millisecondi in cui il main thread è bloccato. Questo è sufficiente per fallire l'Interaction to Next Paint.
Ultima revisione a cura di Arjen Karel a marzo 2026
Table of Contents!
La pipeline di rendering
Per capire perché il reflow è costoso, devi sapere come il browser esegue il rendering di una pagina. Ogni cambiamento visivo passa attraverso un massimo di cinque fasi:
JavaScript → Style → Layout → Paint → Composite
JavaScript (o CSS) scatena un cambiamento visivo. Il browser ricalcola quali stili si applicano. Poi esegue il layout (reflow) per calcolare la geometria. Quindi disegna (paints) i pixel. Infine compone (composites) i livelli insieme.
Non tutti i cambiamenti passano per tutte e cinque le fasi. Questa è l'intuizione chiave. Modifica width o height e scatenerai l'intera pipeline. Modifica background-color e salterai del tutto il layout (solo paint + composite). Modifica transform o opacity e salterai sia layout che paint, passando direttamente al composite. La guida alle prestazioni di rendering di web.dev copre questa pipeline in dettaglio.
I cambiamenti di solo composite sono economici. Quelli di layout non lo sono. A 60 fps il browser ha 16.66ms per frame per fare tutto. Dopo l'overhead del browser, ti rimangono circa 10ms per il tuo codice. Spendili per il reflow e otterrai dei rallentamenti (jank).
Cosa scatena il reflow
Due categorie di cose causano il reflow: modifiche che invalidano il layout corrente e letture JavaScript che forzano il browser a calcolare immediatamente il layout.
Proprietà CSS che scatenano il layout
La modifica di una qualsiasi di queste proprietà forza il reflow del browser:
- Dimensioni:
width,height,padding,border,min-height,max-width - Posizione:
top,right,bottom,left,margin - Modalità di layout:
display,float,position,flex,grid - Testo:
font-size,font-family,font-weight,line-height,text-align,white-space - Contenuto:
overflow,word-wrap
Proprietà come color, background-color, visibility e box-shadow scatenano un repaint ma non un reflow. Proprietà come transform, opacity e filter non ne scatenano nessuno dei due. Queste sono le proprietà da utilizzare per animazioni e transizioni.
Proprietà JavaScript che forzano il layout sincrono
È qui che diventa costoso. Certe proprietà JavaScript forzano il browser a calcolare il layout immediatamente, in modo sincrono, bloccando il tuo script. Paul Irish mantiene un elenco completo (più di 5.000 stelle su GitHub). Le più comuni:
offsetWidth,offsetHeight,offsetTop,offsetLeftclientWidth,clientHeight,clientTop,clientLeftscrollWidth,scrollHeight,scrollTop,scrollLeftgetBoundingClientRect()getComputedStyle()innerText(sì, leggereinnerTextforza il layout)focus()scrollIntoView()
La lettura di una qualsiasi di queste dopo aver modificato una proprietà di layout forza un reflow sincrono. Il browser non può restituire il valore senza prima calcolare il layout. Chrome DevTools segnala i reflow forzati che superano i 30ms come collo di bottiglia delle prestazioni.
Layout thrashing: il pattern da evitare
Il layout thrashing si verifica quando il tuo codice alterna la lettura e la scrittura di proprietà di layout all'interno di un ciclo. Ogni lettura forza un reflow perché la scrittura precedente ha invalidato il layout. Vedo questo pattern costantemente in script di caroselli, plugin di accordion e codice analitico che misura le posizioni degli elementi.
// SBAGLIATO: forza il reflow ad ogni iterazione
for (const el of elements) {
el.style.width = box.offsetWidth + 'px'; // lettura + scrittura = reflow forzato
}
Ogni iterazione legge offsetWidth (forzando il layout) e poi scrive style.width (invalidando il layout). Con 100 elementi, si tratta di 100 reflow forzati invece di uno.
// CORRETTO: raggruppa la lettura, poi raggruppa le scritture
const width = box.offsetWidth; // singola lettura
for (const el of elements) {
el.style.width = width + 'px'; // solo scritture, nessun reflow forzato
}
Una lettura, un reflow, fatto. La guida di web.dev sul layout thrashing mostra questo pattern in dettaglio. Se hai bisogno di leggere le dimensioni dei singoli elementi, raccogli prima tutte le letture, poi esegui tutte le scritture.
Rilevare il reflow forzato in Chrome DevTools
Apri il pannello Performance e registra una traccia. I reflow forzati vengono visualizzati come blocchi viola "Layout" nel flame chart. Se Chrome rileva un layout sincrono forzato, aggiunge un avviso a forma di triangolo rosso. Passaci sopra con il mouse e vedrai esattamente quale riga JavaScript ha scatenato il reflow.
Anche la Console registra un avviso: "Forced reflow while executing JavaScript took Xms". Qualsiasi valore superiore a 30ms è un problema. Ho visto siti in cui un singolo gestore di eventi di scroll scatena 40ms di lavoro di layout su ogni frame.
Anche Lighthouse segnala questo problema. Cerca la diagnostica "Avoid forced reflow" nella categoria Performance.
Come il reflow influisce sui Core Web Vitals
Interaction to Next Paint (INP)
Il reflow ha un impatto diretto sull'INP in due modi. Se un reflow forzato è già in esecuzione quando l'utente fa clic, l'input delay aumenta perché il main thread è bloccato. Se il gestore del clic stesso scatena un lavoro di layout, il processing time aumenta. In entrambi i casi, anche il presentation delay cresce perché il browser deve completare il layout prima di poter dipingere la risposta.
La soglia "buona" per l'INP è di 200ms. Un singolo reflow forzato di 30ms consuma già il 15% di quel budget. Il layout thrashing in un gestore di eventi può facilmente spingere l'INP oltre i 500ms.
Sui siti monitorati da CoreDash, le pagine che raggruppano le letture e le scritture del DOM mostrano punteggi INP migliori di circa il 18% rispetto alle pagine con pattern di layout thrashing.
Largest Contentful Paint (LCP)
Durante il caricamento della pagina, il reflow compete per il tempo del main thread. Il caricamento dei font ne è una causa comune: quando un web font arriva e sostituisce il testo di fallback, il browser esegue il reflow di ogni elemento che utilizza quel font. Su una pagina con molto testo, quel reflow può ritardare il LCP di 100ms o più.
Le immagini senza attributi espliciti width e height causano lo stesso problema. Secondo il Web Almanac 2025, il 62% delle pagine mobile ha ancora almeno un'immagine senza dimensioni. Quando quell'immagine viene caricata, il browser esegue il reflow della pagina per adattarsi alle dimensioni effettive.
Cumulative Layout Shift (CLS)
Il reflow in sé non causa CLS. Il CLS si verifica quando elementi visibili si spostano dopo che l'utente li ha visti. Ma il reflow derivante da contenuti caricati in ritardo (annunci iniettati, immagini senza dimensioni, elementi inseriti dinamicamente) è il meccanismo alla base della maggior parte dei layout shift. Risolvi la causa del reflow e il layout shift scomparirà.
Le transizioni CSS che animano le proprietà di layout sono un'altra fonte. La transizione di height o margin causa un reflow su ogni frame di animazione.
Prevenire il reflow con il CSS moderno
Animazioni solo-composite (composite-only)
Anima transform e opacity invece di width, height, top o left. Queste vengono eseguite sul thread del compositore della GPU e saltano completamente il layout. Vuoi spostare un elemento? Usa transform: translateX(). Vuoi ridimensionarlo visivamente? Usa transform: scale(). Il Web Almanac 2025 ha rilevato che il 40% delle pagine mobile utilizza ancora animazioni non composite. Si tratta del 40% delle pagine che svolgono lavoro di layout non necessario su ogni frame.
CSS containment
La proprietà contain indica al browser che le parti interne di un elemento sono indipendenti dal resto della pagina. Quando qualcosa cambia all'interno di un elemento con containment, il browser esegue il reflow solo di quel sottoalbero invece che dell'intero documento.
article {
contain: content;
}
Questo è particolarmente utile per le pagine con un DOM di grandi dimensioni. Più elementi il browser deve controllare durante il reflow, più tempo impiegherà. Il containment ne limita il raggio d'azione.
content-visibility
content-visibility: auto indica al browser di saltare i calcoli di layout, paint e style per gli elementi che si trovano fuori dallo schermo. Quando Google lo ha testato su una demo di un blog di viaggi, il tempo di rendering è sceso da 232ms a 30ms. Un miglioramento di 7 volte.
.section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
Il contain-intrinsic-size fornisce al browser un'altezza segnaposto in modo che i calcoli della barra di scorrimento rimangano corretti. Questa proprietà è diventata Baseline Newly Available a settembre 2025, il che significa che funziona in tutti i principali browser.
Checklist pratica
- Raggruppa le letture del DOM prima delle scritture. Non alternare mai la lettura di proprietà di layout e la scrittura di modifiche allo stile.
- Imposta dimensioni esplicite per immagini ed embed. Questo previene il reflow durante il caricamento della risorsa.
- Anima solo con
transformeopacity. Queste saltano completamente il layout e il paint. - Usa
contain: contentsu sezioni indipendenti. Questo limita il reflow al sottoalbero modificato. - Aggiungi
content-visibility: autoalle sezioni below-the-fold. Questo salta il layout per i contenuti fuori dallo schermo. - Preferisci flexbox ai float. Il layout flexbox è circa 4 volte più veloce del layout float a parità di numero di elementi.
- Fai yielding al main thread tra le operazioni DOM costose per mantenere la pagina reattiva.
- Rinvia gli script (defer) che modificano il DOM fino al completamento del render iniziale.
Monitora l'impatto reale di queste modifiche con il Real User Monitoring. Gli strumenti di laboratorio come Lighthouse ti mostrano il costo del layout isolato, ma i dati sul campo dimostrano se i tuoi utenti percepiscono effettivamente il miglioramento.
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
