Medir Core Web Vitals en Next.js: Guía de configuración RUM
Configurar Real User Monitoring para Core Web Vitals en Next.js (App Router y Pages Router)

Medir las Core Web Vitals en Next.js
Next.js es un framework de JavaScript sobre React que te permite construir sitios web superrápidos y extremadamente fáciles de usar. Es cierto, Next.js es bastante rápido y tiene muchas características integradas para asegurar que se mantenga rápido. Al menos, en teoría. Con el tiempo, a medida que tu sitio web crece y se añaden más características y quizás cuando no se siguen todas las mejores prácticas, las páginas de Next.js se volverán cada vez más lentas. Esa es probablemente la razón por la que estás visitando esta página :-)
Última revisión por Arjen Karel en marzo de 2026
Para medir y prevenir páginas lentas es importante medir las Core Web Vitals y tomar medidas cuando una métrica está por debajo de su umbral. Las tres Core Web Vitals son Largest Contentful Paint (LCP) para carga (umbral: 2.5 segundos), Interaction to Next Paint (INP) para interactividad (umbral: 200ms), y Cumulative Layout Shift (CLS) para estabilidad visual (umbral: 0.1). Solo el 48% de los orígenes móviles aprueban las tres según el 2025 Web Almanac. Para sitios de Next.js específicamente, el informe de frameworks de Astro de 2023 encontró que solo alrededor del 25% de los orígenes de Next.js aprobaron. Los Server Components y el App Router en Next.js 14 y 15 han mejorado esto, pero medir tus propios datos de campo es la única forma de saber dónde te encuentras.
Olvídate de Lighthouse (más o menos)
Lighthouse es una herramienta de pruebas para las Core Web Vitals. Casi todos los clientes con los que trabajo, en algún momento, empiezan a hablar sobre sus puntuaciones de Lighthouse y cómo no coinciden con sus puntuaciones de Search Console. Lo primero que les digo es esto: olvídate de Lighthouse. Me explicaré:

Lighthouse es una herramienta muy útil que recopila 'datos de laboratorio' para una primera visita sin caché bajo condiciones reguladas. Desafortunadamente, los datos recopilados no reflejan necesariamente los datos de campo. Los datos de campo son recopilados por el navegador cada vez que un usuario carga una de tus páginas. Esos datos luego se envían a Google y se utilizan para determinar tus verdaderas puntuaciones de Core Web Vitals. Este proceso también se llama Real User Monitoring (RUM).
Aquí está lo que la mayoría de los desarrolladores pasan por alto: INP no se puede medir en herramientas de laboratorio en absoluto. Lighthouse no interactúa con tu sitio web, por lo que no tiene datos de interacción. Utiliza el Total Blocking Time como un proxy, pero TBT e INP no son la misma cosa. CLS en herramientas de laboratorio también muestra puntuaciones artificialmente bajas porque Lighthouse no se desplaza ni hace clic por la página. La única forma de obtener números reales de INP y CLS es de usuarios reales.
No me malinterpretes: me encanta Lighthouse. Es una pieza maestra de software y te dará grandes sugerencias que probablemente deberías implementar. Lo que estoy diciendo es que las métricas RUM en un sitio de Next.js no se componen simplemente de vistas sin caché por primera vez. No, las Core Web Vitals en un sitio web de Next.js son más complicadas. Es por eso que una de las primeras cosas que implemento para mis clientes es el Real User Monitoring en tiempo real. Google clasifica basándose en los datos de campo de CrUX, no en las puntuaciones de Lighthouse.
Medir Core Web Vitals en Next.js (App Router)
Si estás utilizando el App Router (Next.js 13+), la forma recomendada de recopilar Core Web Vitals es el hook useReportWebVitals de next/web-vitals. Este hook viene incluido con Next.js en sí, así que no hay nada extra que instalar.
Debido a que el hook requiere la directiva 'use client', la mejor práctica es aislarlo en un componente pequeño. Esto mantiene el límite del cliente ajustado y evita hacer que todo tu layout sea un componente de cliente:
// app/_components/web-vitals.js
'use client'
import { useReportWebVitals } from 'next/web-vitals'
export function WebVitals() {
useReportWebVitals((metric) => {
console.log(metric)
})
return null
}
Luego impórtalo en tu layout raíz:
// app/layout.js
import { WebVitals } from './_components/web-vitals'
export default function Layout({ children }) {
return (
<html>
<body>
<WebVitals />
{children}
</body>
</html>
)
}
Eso es todo. Cada carga de página ahora reportará LCP, INP, CLS, FCP, y TTFB a la consola. Por supuesto, registrar en la consola no es muy útil en producción. Déjame mostrarte cómo enviar los datos a algún lugar útil.
Enviar Core Web Vitals a un endpoint personalizado
La forma más fiable de enviar datos de rendimiento es navigator.sendBeacon(). Está diseñado exactamente para esto: enviar pequeñas cargas útiles (payloads) cuando el usuario abandona la página, sin bloquear la navegación.
// app/_components/web-vitals.js
'use client'
import { useReportWebVitals } from 'next/web-vitals'
export function WebVitals() {
useReportWebVitals((metric) => {
const url = 'https://example.com/analytics'
const body = JSON.stringify(metric)
if (navigator.sendBeacon) {
navigator.sendBeacon(url, body)
} else {
fetch(url, { body: body, method: 'POST', keepalive: true })
}
})
return null
}
Enviar Core Web Vitals a Google Analytics (GA4)
Si utilizas Google Analytics 4 con el fragmento gtag, puedes enviar Core Web Vitals como eventos personalizados:
// app/_components/web-vitals.js
'use client'
import { useReportWebVitals } from 'next/web-vitals'
export function WebVitals() {
useReportWebVitals((metric) => {
window.gtag('event', metric.name, {
event_category: 'Web Vitals',
value: Math.round(metric.name === 'CLS' ? metric.value * 1000 : metric.value),
event_label: metric.id,
non_interaction: true,
})
})
return null
}
Recuerda: cuando leas los datos de Core Web Vitals de cualquier fuente RUM, necesitas usar el percentil 75. Ese es el umbral que Google usa. No el promedio, no la mediana. El p75.
Muestreo en sitios de alto tráfico
En sitios web de alto tráfico tendrá poco sentido recopilar datos de cada usuario. Puedes muestrear el 50% o menos de esta manera:
// app/_components/web-vitals.js
'use client'
import { useReportWebVitals } from 'next/web-vitals'
const inSample = Math.random() >= 0.5
export function WebVitals() {
useReportWebVitals((metric) => {
if (inSample) {
const body = JSON.stringify(metric)
navigator.sendBeacon('/analytics', body)
}
})
return null
}
Medir Core Web Vitals en Next.js (Pages Router)
Si todavía estás en el Pages Router, Next.js proporciona una función incorporada reportWebVitals que exportas desde pages/_app.js. Este es el enfoque más antiguo, pero todavía funciona:
// pages/_app.js
export function reportWebVitals(metric) {
if (metric.label === 'web-vital') {
console.log(metric)
}
}
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}
Los mismos patrones para enviar datos a un endpoint personalizado o Google Analytics se aplican aquí. Simplemente pon la llamada sendBeacon o gtag dentro de la función reportWebVitals en lugar del callback del hook.
Una cosa a tener en cuenta: el Pages Router también reporta métricas personalizadas de Next.js como Next.js-hydration y Next.js-route-change-to-render. Estas te dicen cuánto tiempo toman la hidratación y las navegaciones en el lado del cliente. La versión del App Router todavía no reporta estas métricas personalizadas.
Herramientas de monitorización de terceros
Hay algunas herramientas de terceros que recopilan Core Web Vitals en Next.js. Vercel tiene @vercel/speed-insights que funciona de forma predeterminada si despliegas en Vercel. Está bien para una visión general rápida, pero no desglosa las métricas en subpartes, los paneles son básicos y estás atado al ecosistema de Vercel.
NewRelic y Sentry ambos recopilan Core Web Vitals pero no son herramientas de rendimiento. Son herramientas de seguimiento de errores y APM que añadieron Core Web Vitals como una característica. Ambos inyectan scripts que compiten por los recursos de red tempranos y el tiempo del hilo principal (main thread). He visto a Sentry añadir 200ms de tiempo de bloqueo en móviles. Eso es irónico para una herramienta que se supone que debe ayudarte a monitorizar el rendimiento.
CoreDash es lo que uso y recomiendo. Está construido específicamente para Core Web Vitals. Cada métrica se desglosa en subpartes para que sepas exactamente a dónde va el tiempo. Los paneles te muestran tendencias, regresiones y desgloses a nivel de página sin tener que hacer clic en cinco menús. Y la integración MCP te permite conectar tus datos de campo en herramientas de IA y hacer preguntas sobre tu rendimiento en lenguaje sencillo. Simplemente pregunta "¿qué está causando los cambios de diseño en móviles?" y obtén la respuesta de tus propios datos.
Si quieres solucionar problemas con scripts de terceros o eliminar el CSS que bloquea el renderizado en Next.js, también he escrito guías dedicadas para esos temas.
I have done this before at your scale.
Complex platforms, large dev teams, legacy code. I join your team as a specialist, run the performance track, and hand it back in a state you can maintain.
Discuss Your Situation
