Reflow del navegador: qué lo activa y cómo afecta a las Core Web Vitals
El reflow recalcula las posiciones de los elementos y bloquea el hilo principal. Descubre qué lo activa, cómo detectarlo y cómo prevenirlo.

¿Qué es el reflow del navegador?
El reflow es lo que ocurre cuando el navegador recalcula la posición y el tamaño de los elementos en la página. Cada vez que cambias el DOM o modificas una propiedad CSS que afecta al layout, el navegador tiene que averiguar dónde va todo de nuevo. Este cálculo bloquea el hilo principal. No ocurre nada más hasta que termina.
Un solo reflow en una página sencilla tarda microsegundos. Pero si desencadenas cientos de ellos durante una interacción del usuario, te enfrentarás a cientos de milisegundos de tiempo de bloqueo en el hilo principal. Eso es suficiente para reprobar la métrica Interaction to Next Paint.
Última revisión por Arjen Karel en marzo de 2026
Table of Contents!
El pipeline de renderizado
Para entender por qué el reflow es costoso, necesitas saber cómo renderiza una página el navegador. Cada cambio visual pasa por hasta cinco etapas:
JavaScript → Style → Layout → Paint → Composite
JavaScript (o CSS) activa un cambio visual. El navegador recalcula qué estilos se aplican. Luego ejecuta el layout (reflow) para calcular la geometría. Después pinta (paints) los píxeles. Finalmente, compone (composites) las capas juntas.
No todos los cambios pasan por las cinco etapas. Esa es la clave. Si cambias width o height, activas todo el pipeline. Si cambias background-color, te saltas el layout por completo (solo paint + composite). Si cambias transform u opacity, te saltas tanto layout como paint, yendo directamente a composite. La guía de rendimiento de renderizado de web.dev cubre este pipeline en detalle.
Los cambios que solo requieren composite son baratos. Los cambios de layout no lo son. A 60fps, el navegador tiene 16.66ms por frame para hacer todo. Después de descontar la sobrecarga del navegador, te quedan aproximadamente 10ms para tu código. Si gastas eso en reflow, obtendrás jank (tirones).
Qué desencadena el reflow
Dos categorías de cosas causan el reflow: los cambios que invalidan el layout actual y las lecturas de JavaScript que obligan al navegador a calcular el layout inmediatamente.
Propiedades CSS que activan el layout
Cambiar cualquiera de estas propiedades obliga al navegador a realizar un reflow:
- Dimensiones:
width,height,padding,border,min-height,max-width - Posición:
top,right,bottom,left,margin - Modo de layout:
display,float,position,flex,grid - Texto:
font-size,font-family,font-weight,line-height,text-align,white-space - Contenido:
overflow,word-wrap
Propiedades como color, background-color, visibility y box-shadow desencadenan un repaint, pero no un reflow. Propiedades como transform, opacity y filter no desencadenan ninguno de los dos. Estas son las propiedades que deseas usar para las animaciones y transiciones.
Propiedades de JavaScript que fuerzan un layout síncrono
Aquí es donde resulta costoso. Ciertas propiedades de JavaScript obligan al navegador a calcular el layout ahora mismo, de forma síncrona, bloqueando tu script. Paul Irish mantiene una lista exhaustiva (más de 5,000 estrellas en GitHub). Las más comunes son:
offsetWidth,offsetHeight,offsetTop,offsetLeftclientWidth,clientHeight,clientTop,clientLeftscrollWidth,scrollHeight,scrollTop,scrollLeftgetBoundingClientRect()getComputedStyle()innerText(sí, leerinnerTextfuerza el layout)focus()scrollIntoView()
Leer cualquiera de estas propiedades después de cambiar una propiedad de layout fuerza un reflow síncrono. El navegador no puede devolver el valor sin calcular el layout primero. Las DevTools de Chrome marcan los reflows forzados que superan los 30ms como un cuello de botella de rendimiento.
Layout thrashing: el patrón a evitar
El layout thrashing ocurre cuando tu código alterna entre leer y escribir propiedades de layout en un bucle. Cada lectura fuerza un reflow porque la escritura anterior invalidó el layout. Veo este patrón constantemente en scripts de carruseles, plugins de acordeón y código de analítica que mide las posiciones de los elementos.
// MAL: fuerza un reflow en cada iteración
for (const el of elements) {
el.style.width = box.offsetWidth + 'px'; // lectura + escritura = reflow forzado
}
Cada iteración lee offsetWidth (forzando el layout) y luego escribe style.width (invalidando el layout). Con 100 elementos, eso supone 100 reflows forzados en lugar de uno.
// BIEN: agrupar la lectura, luego agrupar las escrituras
const width = box.offsetWidth; // lectura única
for (const el of elements) {
el.style.width = width + 'px'; // solo escrituras, sin reflows forzados
}
Una lectura, un reflow y listo. La guía de web.dev sobre layout thrashing muestra este patrón en detalle. Si necesitas leer los tamaños individuales de los elementos, recopila primero todas las lecturas y luego realiza todas las escrituras.
Cómo detectar el reflow forzado en las DevTools de Chrome
Abre el panel Performance y graba una traza. Los reflows forzados aparecen como bloques morados de "Layout" en el gráfico de llama (flame chart). Si Chrome detecta un layout síncrono forzado, añade una advertencia con un triángulo rojo. Pasa el ratón por encima y verás exactamente qué línea de JavaScript desencadenó el reflow.
La Consola también registra una advertencia: "Forced reflow while executing JavaScript took Xms". Cualquier valor superior a 30ms es un problema. He visto sitios donde un solo manejador de eventos de scroll desencadena 40ms de trabajo de layout en cada frame.
Lighthouse también señala esto. Busca el diagnóstico "Avoid forced reflow" en la categoría de Rendimiento (Performance).
Cómo afecta el reflow a las Core Web Vitals
Interaction to Next Paint (INP)
El reflow impacta directamente en INP de dos maneras. Si ya se está ejecutando un reflow forzado cuando el usuario hace clic, el retraso de entrada (input delay) aumenta porque el hilo principal está bloqueado. Si el propio manejador de clics desencadena trabajo de layout, el tiempo de procesamiento (processing time) aumenta. De cualquier manera, el retraso de presentación (presentation delay) también crece porque el navegador debe completar el layout antes de poder pintar la respuesta.
El umbral "bueno" de INP es de 200ms. Un solo reflow forzado de 30ms ya consume el 15% de ese presupuesto. El layout thrashing en un manejador de eventos puede empujar fácilmente el INP más allá de los 500ms.
En los sitios monitorizados por CoreDash, las páginas que agrupan las lecturas y escrituras del DOM muestran puntuaciones de INP aproximadamente un 18% mejores en comparación con las páginas que presentan patrones de layout thrashing.
Largest Contentful Paint (LCP)
Durante la carga de la página, el reflow compite por el tiempo del hilo principal. La carga de fuentes es una fuente común de esto: cuando llega una fuente web y reemplaza el texto de fallback, el navegador aplica un reflow a todos los elementos que usan esa fuente. En una página con mucho texto, ese reflow puede retrasar el LCP 100ms o más.
Las imágenes sin atributos explícitos de width y height causan el mismo problema. Según el Web Almanac de 2025, el 62% de las páginas móviles todavía tienen al menos una imagen sin dimensiones. Cuando esa imagen se carga, el navegador aplica un reflow a la página para acomodar el tamaño real.
Cumulative Layout Shift (CLS)
El reflow en sí no causa CLS. El CLS ocurre cuando los elementos visibles se mueven después de que el usuario los ve. Pero el reflow proveniente de contenido de carga tardía (anuncios inyectados, imágenes sin tamaño, elementos insertados dinámicamente) es el mecanismo detrás de la mayoría de los cambios de layout (layout shifts). Corrige el desencadenante del reflow y el cambio de layout desaparecerá.
Las transiciones CSS que animan propiedades de layout son otra fuente. Transicionar height o margin causa un reflow en cada frame de animación.
Cómo prevenir el reflow con CSS moderno
Animaciones que solo usan composite
Anima transform y opacity en lugar de width, height, top o left. Estos se ejecutan en el hilo del compositor de la GPU y omiten el layout por completo. ¿Quieres mover un elemento? Usa transform: translateX(). ¿Quieres redimensionarlo visualmente? Usa transform: scale(). El Web Almanac de 2025 descubrió que el 40% de las páginas móviles todavía usan animaciones sin composite (non-composited). Eso significa que el 40% de las páginas realizan trabajo de layout innecesario en cada frame.
CSS containment
La propiedad contain le dice al navegador que el interior de un elemento es independiente del resto de la página. Cuando algo cambia dentro de un elemento contenido, el navegador solo aplica reflow a ese subárbol en lugar de a todo el documento.
article {
contain: content;
}
Esto es especialmente útil para páginas con un DOM grande. Cuantos más elementos tenga que revisar el navegador durante el reflow, más tiempo tardará. El containment limita el radio de impacto.
content-visibility
content-visibility: auto le indica al navegador que omita los cálculos de layout, paint y estilo para los elementos que están fuera de la pantalla. Cuando Google probó esto en una demo de un blog de viajes, el tiempo de renderizado bajó de 232ms a 30ms. Una mejora de 7 veces.
.section {
content-visibility: auto;
contain-intrinsic-size: auto 500px;
}
El contain-intrinsic-size le da al navegador una altura de marcador de posición para que los cálculos de la barra de desplazamiento sigan siendo correctos. Esta propiedad pasó a ser Baseline Newly Available en septiembre de 2025, lo que significa que funciona en todos los navegadores principales.
Lista de verificación práctica
- Agrupa las lecturas del DOM antes que las escrituras. Nunca alternes entre leer propiedades de layout y escribir cambios de estilo.
- Establece dimensiones explícitas en imágenes e incrustaciones. Esto evita el reflow cuando se carga el recurso.
- Anima solo con
transformyopacity. Estos omiten el layout y el paint por completo. - Usa
contain: contenten secciones independientes. Esto limita el reflow al subárbol modificado. - Añade
content-visibility: autoa las secciones below-the-fold. Esto omite el layout para el contenido fuera de pantalla. - Prefiere flexbox antes que floats. El layout de flexbox es aproximadamente 4 veces más rápido que el layout con float para el mismo número de elementos.
- Haz yield al hilo principal entre operaciones costosas del DOM para mantener la página responsiva.
- Difiere los scripts que modifican el DOM hasta después de que se complete el renderizado inicial.
Monitoriza el impacto real de estos cambios con RUM (Real User Monitoring). Las herramientas de laboratorio como Lighthouse te muestran el costo del layout de forma aislada, pero los datos de campo muestran si tus usuarios realmente experimentan la mejora.
I make sites pass Core Web Vitals.
500K+ pages for major European publishers and e-commerce platforms. I write the fixes and verify them with field data.
How I work
