Core Web Vitals en 2026: cómo medir LCP, INP y CLS con datos reales (y no solo con Lighthouse)
Los umbrales de los Core Web Vitals no cambiaron en 2026 (LCP 2,5 s, INP 200 ms, CLS 0,1), pero sí cambió cómo se miden y cómo se depuran. Esta guía sirve para sacar tus números reales de CrUX y Search Console, encontrar con LoAF la interacción que falla y arreglar solo lo que mueve la aguja.
Y hay una novedad concreta este mes: las aplicaciones de una sola página dejaron de ser un punto ciego.
Qué son los Core Web Vitals (y qué no)
Los Core Web Vitals son el subconjunto de métricas de rendimiento web que Google considera aplicables a todas las páginas y que se miden con datos de usuarios reales. Son tres y cada una cubre una dimensión distinta.
LCP: cuánto tarda en verse lo importante
Largest Contentful Paint mide el tiempo hasta que se pinta el elemento de contenido más grande dentro del viewport: normalmente la imagen del héroe, un titular grande o un bloque de texto. Es la métrica de carga.
Lee también
INP: cuánto tarda la interfaz en responderte
Interaction to Next Paint mide el tiempo que pasa desde que el usuario interactúa (clic, toque o tecla) hasta que la interfaz muestra el siguiente fotograma con la respuesta. Reemplazó a First Input Delay el 12 de marzo de 2024, y FID quedó retirada. Es la métrica de interactividad y, hoy, la que más sitios suspende.
CLS: cuánto se mueve lo que ya estabas leyendo
Cumulative Layout Shift mide la inestabilidad visual: cuánto se desplaza el contenido sin que el usuario lo provoque. Un banner que aparece sobre el párrafo que estabas leyendo es CLS puro.
Umbrales: los mismos números, medidos al percentil 75
Los umbrales no cambiaron en 2026:
- LCP: 2,5 segundos o menos.
- INP: 200 milisegundos o menos.
- CLS: 0,1 o menos.
La parte que casi nadie explica es cómo se califica. No se usa tu portátil ni tu conexión: el número sale de datos de campo y se evalúa al percentil 75. Es decir, que el 75 % de las visitas lo haga mejor que ese valor; el 25 % restante puede ir mucho peor y no cuenta. Por eso un promedio bonito puede esconder un desastre en móvil.
Los datos que Google mira no son los de tu portátil
Datos de campo frente a datos de laboratorio
Los datos de campo vienen de usuarios reales, en sus dispositivos y redes. Los de laboratorio se generan en un entorno controlado. El veredicto de Google sobre tu sitio se basa en los de campo.
Qué es CrUX y por qué tu sitio puede no tener datos todavía
CrUX (Chrome User Experience Report) es el conjunto de datos agregados con el que Google mide los Core Web Vitals. Se actualiza cada mes y solo aparece un origen si tiene suficiente tráfico; si tu sitio es nuevo o pequeño, simplemente no está ahí, y eso no significa que vaya mal: significa que no hay medición.
Lighthouse sirve para diagnosticar, no para aprobar
Lighthouse mide laboratorio. Como puntuación de rendimiento es excelente para reproducir problemas y verificar que un arreglo no rompió nada, pero el número que Google evalúa no sale de ahí. Confundir los dos es el error más común y el que hace perder tiempo optimizando hasta el 100.
Cómo medir tu sitio con datos reales, paso a paso
Paso 1: leer el informe de Core Web Vitals en Search Console
Agrupa URLs por estado y tipo de página, así que sirve para ver patrones por plantilla, no para un URL suelto. Empieza por el grupo con más URLs afectadas: ahí está el mayor retorno.
Paso 2: confirmar con PageSpeed Insights y la API de CrUX
PageSpeed Insights mezcla datos de campo de CrUX con una auditoría de laboratorio. Si tu sitio tiene poco tráfico, puede no mostrar datos de campo y solo verás laboratorio: tenlo en cuenta antes de sacar conclusiones. La API de CrUX, y el conjunto de datos en BigQuery, permiten consultar tu propio histórico y graficarlo.
Paso 3: medir con la librería web-vitals en tu propio sitio
La vía directa es medir tú. La librería oficial web-vitals (versión 6) expone una función por métrica y una variante de atribución que, además del valor, te dice qué elemento o qué interacción se portó mal. El siguiente ejemplo es el patrón mínimo con atribución: cada métrica se envía a tu propio endpoint.
import {onCLS, onINP, onLCP} from 'web-vitals/attribution';
function send({name, value, delta, id, attribution}) {
let target = attribution.target;
if (name === 'INP') target = attribution.interactionTarget;
if (name === 'CLS') target = attribution.largestShiftTarget;
navigator.sendBeacon('/rum', JSON.stringify({name, value, delta, id, target}));
}
onCLS(send);
onINP(send);
onLCP(send);Dos detalles prácticos: no llames a estas funciones varias veces por carga de página sin motivo (cada una crea su propio observador) y recuerda que INP no se reporta si el usuario no interactúa con la página.
Paso 4: interpretar la atribución
El valor sin contexto dice poco. Con la variante de atribución obtienes el selector del elemento culpable en LCP y CLS, y en INP el elemento objetivo, el tipo de evento y el tiempo repartido por fases. Con eso, la conversación deja de ser "la web va lenta" y pasa a ser "este botón, en este tipo de evento".
Cómo depurar lo que falla
INP: retraso de entrada, procesamiento y presentación
El INP se compone de tres tramos: el retraso de entrada (cuánto espera la interacción hasta empezar a procesarse), el procesamiento (tu código) y la presentación (pintar el resultado). Si el retraso de entrada es el tramo grande, el problema casi nunca está en tu manejador del evento, sino en el script que ya estaba corriendo cuando el usuario hizo clic.
La API LoAF: quién bloqueó el hilo y en qué se fue el tiempo
Long Animation Frames es la evolución de la Long Tasks API y la herramienta de referencia para depurar INP: atribuye el trabajo bloqueante a scripts y fases concretas, y separa lo que se fue en ejecución de script de lo que se fue en estilo y layout. Con eso se pasa de la sospecha a la lista de culpables.
Tareas largas y scheduler.yield(): el detalle del await
Para partir el trabajo se usa scheduler.yield(). El aviso que mucha gente se salta: esa función solo programa la tarea, quien realmente pausa es el await. Y cuidado con los métodos iterativos: forEach no espera a que cada callback termine, así que un forEach con await dentro no hace lo que parece.
async function runJobs(jobs) {
for (const job of jobs) {
job();
await scheduler.yield();
}
}Además, ceder el hilo en cada paso tiene coste. Lo razonable es agrupar trabajo y ceder solo cuando la tarea lleva un tiempo largo, con un umbral habitual de 50 milisegundos para no seguir creando tareas largas. Y como no todos los navegadores lo soportan todavía, conviene un respaldo con setTimeout envuelto en una promesa.
LCP: separar TTFB, carga del recurso y renderizado
Del LCP, primero identifica el elemento. Después mira en qué tramo se va el tiempo: si el TTFB domina, el problema es el servidor; si domina la carga del recurso, es la imagen o su peso; si domina el renderizado, suele ser CSS o JavaScript bloqueante delante del contenido principal.
CLS: imágenes sin dimensiones, avisos y fuentes
Las causas típicas: imágenes sin ancho y alto declarados, bloques insertados (avisos, banners, cookies) sobre contenido ya pintado, y fuentes web que cambian el tamaño del texto al cargar.
Cómo arreglar cada métrica
LCP: servidor, imágenes y CSS crítico
Orden de ataque: primero el TTFB, con caché de página y una respuesta de servidor decente; después las imágenes, con dimensiones correctas, formato moderno, el tamaño adecuado a cada pantalla y prioridad alta solo para la imagen principal; por último, el CSS crítico y evitar que el contenido principal espere por fuentes o por scripts.
Si tu sitio es Laravel, el tramo del servidor ya está explicado en el post sobre caché de página y TTFB en Laravel 13, así que no lo repetimos aquí.
INP: menos JavaScript, menos trabajo dentro del manejador
Lo que más mueve la aguja: reducir scripts de terceros, diferir y dividir lo que no es crítico, no hacer trabajo pesado dentro del manejador del evento y no repintar de más. Si usas Livewire o Alpine, actualiza bloques pequeños en lugar de marcos enteros. Las técnicas de lazy loading y code splitting son el siguiente escalón natural.
CLS: reservar el hueco antes de pintar
Declara dimensiones o proporción de aspecto, reserva un espacio fijo para banners y avisos, elige bien el comportamiento de las fuentes y no insertes contenido por encima de lo que el usuario ya está leyendo.
Lo nuevo de 2026: medir también las navegaciones suaves
Por qué las aplicaciones de una sola página quedaban ciegas
Hasta ahora, cuando navegabas dentro de una aplicación de una sola página, la medición solo registraba la carga inicial: los cambios de vista posteriores no se consideraban navegaciones y todas las interacciones de la sesión se atribuían a esa primera página.
Qué cambia con las soft navigations (y qué no)
Chrome 151 lanzó la API de soft navigations y la librería web-vitals incorporó el soporte desde la versión 6, con la opción reportSoftNavs. Desde este mes, CrUX publica variantes experimentales de las tres métricas que incluyen navegaciones suaves.
import {onCLS, onINP, onLCP} from 'web-vitals';
onCLS(console.log, {reportSoftNavs: true});
onINP(console.log, {reportSoftNavs: true});
onLCP(console.log, {reportSoftNavs: true});Los números del corte de septiembre de 2026, publicado el 13 de octubre, dan la medida del cambio: sobre 18,37 millones de orígenes, el 68,3 % tenía buen LCP, el 81,7 % buen CLS, el 85,4 % buen INP y solo el 55,9 % aprobaba las tres. Si se incluyen las navegaciones suaves, esas cifras suben a 72,1 %, 85,1 %, 87,4 % y 59,5 % respectivamente. Ojo con la lectura: no es que los sitios hayan mejorado, es que se mide a otra población.
Qué no cambia: los umbrales siguen igual y las cifras estables de Google no se movieron mientras estas variantes siguen en etapa experimental. El equipo de Chrome apunta a graduarlas en mayo de 2027, y recién entonces Search Console pasará a usarlas. Qué hacer ya: actualizar la librería, etiquetar las rutas internas y empezar a comparar tu propio antes y después.
El caso de Laravel 13 con Blade y Tailwind
Si el sitio es Laravel con Blade, Tailwind y Vite, el orden que funciona es este. Primero TTFB: caché de página o de respuesta, consultas cacheadas y nada de trabajo pesado en el arranque. Después imágenes responsivas bien servidas y @vite sin bloquear el render. Luego JavaScript diferido y componentes pequeños. Y, por último, huecos reservados en Blade para cualquier bloque que aparezca después (avisos, banners, contenido cargado por JavaScript), que es donde suelen nacer los problemas de CLS en este stack.
Checklist: qué hacer esta semana en tu sitio
- Mira Search Console por grupos de páginas y elige la peor plantilla, no el peor URL.
- Confirma con PageSpeed Insights si hay datos de campo; si no los hay, no hay veredicto posible.
- Instala la librería web-vitals con atribución y recoge al menos una semana de datos propios.
- Reproduce el caso con DevTools y la API LoAF: busca el script y la fase, no la sensación.
- Arregla una cosa, mide el mismo tipo de página y compara el percentil 75 antes y después.
- Deja Lighthouse CI en el pipeline solo como red de seguridad, nunca como objetivo.
Y cómo no engañarte: cambia una variable a la vez, mide el mismo tipo de página y no te fíes de una mejora que solo aparece en tu portátil. Cambiar la métrica es fácil; cambiar la distribución de usuarios que la sufre es lo que suma.
Conclusión
Medir con datos reales antes de tocar código, arreglar el tramo correcto y volver a medir. Los umbrales de 2026 son los de siempre; lo nuevo es que ahora también se pueden medir las navegaciones internas de las aplicaciones de una sola página.
Si te interesa el lado técnico del SEO, en el blog tienes la guía de SEO técnico en Laravel 13, y si tu cuello de botella está en el servidor, empieza por el post de caché de página y TTFB. Sigue leyendo Blender Deluxe para el siguiente escalón: medir, arreglar y verificar.


