Lección 1 de 413 min
Medir: Core Web Vitals y herramientas
LCP, INP y CLS, datos de laboratorio frente a datos de campo, Lighthouse, PageSpeed Insights y Chrome DevTools.
En tu portátil, con fibra, la tienda carga al instante. Pero la mayoría de tus clientes entra desde un móvil de gama media con una conexión irregular, y para ellos la foto del producto tarda cinco segundos en aparecer y el botón de comprar se queda congelado al pulsarlo. Muchos se van antes de terminar la compra.
Google también lo nota: las Core Web Vitals forman parte de las señales de experiencia de página que tiene en cuenta su buscador. Por eso rendimiento, SEO y analítica van de la mano en este módulo. Y todo empieza por medir bien: qué métricas importan, en qué se diferencian los datos de laboratorio de los de usuarios reales y qué herramienta usar en cada momento.
Core Web Vitals
Son tres métricas que resumen la experiencia de carga, de respuesta y de estabilidad visual de una página. Cada una tiene un umbral de «bueno» y otro de «malo»; entre ambos está la zona de «necesita mejorar».
Las Core Web Vitals
Tres métricas de experiencia real: cuánto tarda en cargar, en responder y si se mueve.
- Métricas:
- LCP, INP, CLS
- Se evalúa:
- Percentil 75
LCP mide la carga, INP la capacidad de respuesta y CLS la estabilidad visual. Google las evalúa con datos de visitas reales y mira el percentil 75: una página aprueba una métrica si al menos tres de cada cuatro visitas están en la zona buena. Se evalúan por separado en móvil y en escritorio.
En 2024, INP sustituyó como Core Web Vital a FID, que solo medía el retraso de la primera interacción. Las tres forman parte de las señales de experiencia de página de Google Search. No es el factor que más pesa, porque la relevancia del contenido va por delante, pero entre páginas parecidas, la experiencia cuenta.
Úsalo cuando
Como objetivo común entre desarrollo, producto y marketing. Google Search Console tiene un informe de Core Web Vitals que agrupa tus páginas por estado.
Ten en cuenta
No son las únicas métricas útiles. El TTFB (lo que tarda en llegar el primer byte) y el FCP (el primer contenido pintado) no son Core Web Vitals, pero ayudan mucho a diagnosticar un LCP malo.
Métrica Qué mide Bueno Malo
LCP Carga del contenido ≤ 2,5 s > 4 s
INP Respuesta a la interacción ≤ 200 ms > 500 ms
CLS Estabilidad visual ≤ 0,1 > 0,25
Se mira el percentil 75 de las visitas reales,
por separado en móvil y en escritorio.LCP (Largest Contentful Paint)
Cuánto tarda en pintarse el elemento más grande visible: la foto principal o el titular.
- Bueno:
- ≤ 2,5 s
- Malo:
- > 4 s
LCP mide el tiempo desde que empieza la navegación hasta que se pinta el bloque de imagen o de texto más grande que se ve sin hacer scroll. En una tienda suele ser la foto del producto; en un blog, el titular o la imagen de portada.
Las causas típicas de un LCP malo son un servidor lento, CSS o JavaScript que bloquean el renderizado, una imagen principal pesada o que el navegador descubre tarde, y el error clásico: cargarla en diferido con loading="lazy". Lo verás a fondo en la lección de imágenes.
Úsalo cuando
Es la primera métrica que debes mirar en cualquier página de entrada: la portada, una ficha de producto, un artículo.
Ten en cuenta
El elemento LCP no es siempre el que crees, y puede cambiar entre móvil y escritorio. Compruébalo antes de optimizar.
// Pégalo en la consola y recarga: muestra el tiempo y el elemento LCP
new PerformanceObserver((lista) => {
const entradas = lista.getEntries();
const ultima = entradas[entradas.length - 1];
console.log("LCP:", Math.round(ultima.startTime), "ms", ultima.element);
}).observe({ type: "largest-contentful-paint", buffered: true });INP (Interaction to Next Paint)
Cuánto tarda la página en reaccionar visualmente a un clic, un toque o una tecla.
- Bueno:
- ≤ 200 ms
- Malo:
- > 500 ms
- Sustituyó a:
- FID, en 2024
INP mide, para cada interacción, el tiempo que pasa desde que el usuario pulsa hasta que el navegador pinta el siguiente fotograma. El valor de la página es, aproximadamente, el de su peor interacción durante la visita. Si alguien pulsa «Añadir al carrito» y no ve nada durante medio segundo, esa visita tiene un INP malo.
Casi siempre la culpa es del hilo principal ocupado: tareas de JavaScript largas, manejadores de eventos que hacen demasiado o actualizaciones enormes del DOM. Se arregla mostrando primero la respuesta visual, dividiendo el trabajo en trozos que cedan el hilo al navegador, moviendo cálculos a un web worker y, sobre todo, enviando menos JavaScript.
Úsalo cuando
En cualquier página con interacción: formularios, filtros, carritos, menús. Es la métrica que más sufre en las aplicaciones con mucho JavaScript.
Ten en cuenta
Solo se puede medir con interacciones reales, así que una prueba de laboratorio de carga no te da el INP. Para cederle el hilo al navegador también existe scheduler.yield(), pero comprueba su soporte antes de depender de él.
boton.addEventListener("click", async () => {
// 1. Primero, la respuesta visual
boton.disabled = true;
estado.textContent = "Añadiendo…";
// 2. Cede el hilo principal: el navegador puede pintar ya
await new Promise((resolver) => setTimeout(resolver, 0));
// 3. Ahora sí, el trabajo pesado
recalcularTotales(carrito);
estado.textContent = "Añadido";
});CLS (Cumulative Layout Shift)
Cuánto se mueve el contenido sin que el usuario haga nada.
- Bueno:
- ≤ 0,1
- Malo:
- > 0,25
CLS suma los saltos de diseño inesperados: vas a pulsar un enlace y, justo entonces, aparece un banner encima y pulsas otra cosa. Cada salto puntúa según cuánta pantalla se mueve y cuánta distancia, y la métrica se queda con la peor ráfaga de saltos de la visita. No tiene unidades: es una puntuación.
Las causas típicas son imágenes y vídeos sin dimensiones, anuncios o banners que se insertan sobre el contenido, fuentes web que cambian el tamaño del texto al cargar y contenido que llega tarde por JavaScript. Los movimientos justo después de una interacción del usuario, como abrir un acordeón, no cuentan.
Úsalo cuando
En páginas con imágenes, anuncios, avisos de cookies o contenido que se carga por partes.
Ten en cuenta
Reserva el espacio antes de que llegue el contenido: width y height en las imágenes, una altura mínima para el banner. Y anima con transform, que no mueve a los elementos vecinos, en lugar de con top o margin.
<!-- Mal: el navegador no sabe cuánto ocupa hasta descargarla -->
<img src="zapatillas.jpg" alt="Zapatillas rojas">
<!-- Bien: reserva el hueco desde el principio -->
<img src="zapatillas.jpg" alt="Zapatillas rojas" width="800" height="600">
<style>
/* Hueco fijo para el banner de ofertas que llega más tarde */
.banner-ofertas { min-height: 90px; }
</style>Datos de laboratorio y datos de campo
Hay dos formas de medir, y necesitas las dos: en un entorno controlado, para entender y comparar, y en los dispositivos de tus usuarios, para saber la verdad.
Laboratorio frente a campo
Una prueba controlada y repetible frente a lo que viven de verdad tus usuarios.
- Laboratorio:
- Repetible
- Campo:
- Real
- CrUX:
- Últimos 28 días
Los datos de laboratorio salen de cargar la página en condiciones fijas: un dispositivo, una red simulada, una sola visita. Son reproducibles, así que sirven para depurar y para comparar el antes y el después de un cambio. Pero no son tus usuarios.
Los datos de campo se recogen en los dispositivos y redes reales de quienes visitan tu web. Incluyen el móvil antiguo, el tren que entra en un túnel y la pestaña en segundo plano. Google publica los suyos en el CrUX (Chrome User Experience Report): datos de usuarios de Chrome que han aceptado compartirlos, agregados durante los últimos 28 días, para los sitios y páginas con tráfico suficiente. Son los que usa para sus señales de búsqueda.
Úsalo cuando
Laboratorio para diagnosticar y evitar regresiones antes de publicar; campo para saber si has mejorado de verdad y qué ve Google.
Ten en cuenta
Es muy habitual que el laboratorio salga en verde y el campo en rojo: tu equipo y tu red son mejores que los de tus usuarios. Cuando no coincidan, manda el campo.
curl -s "https://chromeuxreport.googleapis.com/v1/records:queryRecord?key=TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{"origin": "https://tienda.com", "formFactor": "PHONE"}'
# Devuelve el percentil 75 de LCP, INP, CLS y otras métricas en móvilesPageSpeed Insights
Una web de Google que junta los datos de campo de CrUX y una prueba de Lighthouse.
- Campo:
- CrUX
- Laboratorio:
- Lighthouse
Escribes una URL en PageSpeed Insights y obtienes dos bloques. Arriba, los datos de campo del CrUX para esa página y para todo el sitio, con la evaluación de las Core Web Vitals: aprobada o no. Abajo, una prueba de laboratorio con Lighthouse ejecutada en los servidores de Google, con sugerencias concretas de mejora.
Tiene pestañas para móvil y escritorio, y una API para automatizar las consultas.
Úsalo cuando
Para una revisión rápida de cualquier página pública, incluida la de la competencia, y para ver de un vistazo qué opina Google de tus visitas reales.
Ten en cuenta
Los datos de campo solo aparecen si la página tiene suficiente tráfico de Chrome, y llegan con retraso: una mejora tarda semanas en reflejarse. La puntuación de laboratorio varía de una ejecución a otra.
curl "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=https://tienda.com&strategy=mobile"
# loadingExperience → datos de campo del CrUX (percentil 75)
# lighthouseResult → el informe de laboratorio completoMedir usuarios reales con web-vitals
Una pequeña librería de Google que mide las Core Web Vitals en cada visita y te las entrega.
- Tipo:
- RUM (campo)
- Paquete:
- web-vitals
La librería web-vitals mide LCP, INP y CLS, además de FCP y TTFB, en los navegadores de tus usuarios y de la misma forma que lo hace Chrome. Cada vez que tiene un valor, llama a tu función, y tú lo envías a tu herramienta de analítica o a tu propio servidor.
Así tienes tus propios datos de campo, que es lo que se llama RUM (Real User Monitoring): por página, por dispositivo, por país o por versión desplegada. Y como llegan junto al resto de tu analítica, puedes cruzar rendimiento con negocio: ¿convierten menos las visitas con un LCP malo? La versión web-vitals/attribution añade qué elemento o qué interacción causó cada valor.
Úsalo cuando
En cualquier web con tráfico que te importe, sobre todo si no tienes tráfico suficiente para el CrUX o necesitas más detalle del que da. En el módulo de observabilidad verás herramientas de RUM comerciales.
Ten en cuenta
Algunas métricas dependen de APIs que no todos los navegadores implementan, así que tus datos vendrán sobre todo de navegadores basados en Chromium. Y CLS e INP se envían al final de la visita: usa navigator.sendBeacon para que no se pierdan al cerrar la pestaña.
import { onCLS, onINP, onLCP } from "web-vitals";
function enviar(metrica) {
const datos = JSON.stringify({
nombre: metrica.name, // "LCP", "INP" o "CLS"
valor: metrica.value,
valoracion: metrica.rating, // "good", "needs-improvement" o "poor"
pagina: location.pathname,
});
// sendBeacon sigue funcionando aunque el usuario cierre la pestaña
navigator.sendBeacon("/analitica", datos);
}
onCLS(enviar);
onINP(enviar);
onLCP(enviar);Diagnosticar en tu equipo
Los datos de campo te dicen que hay un problema; las herramientas de laboratorio te dicen por qué.
Lighthouse
Una auditoría automática de rendimiento, accesibilidad, buenas prácticas y SEO.
- Tipo:
- Laboratorio
- Aproxima el INP con:
- TBT
Lighthouse es una herramienta de código abierto de Google que carga una página en condiciones controladas y la puntúa de 0 a 100 en cuatro categorías: rendimiento, accesibilidad, buenas prácticas y SEO. Por defecto simula un móvil de gama media con una conexión lenta.
La puntuación de rendimiento es una media ponderada de métricas de laboratorio, entre ellas LCP, CLS y el TBT (Total Blocking Time, el tiempo que el hilo principal estuvo bloqueado), que hace de aproximación al INP. Debajo vienen las oportunidades: qué cambiar y cuánto ahorrarías. Se ejecuta desde el panel Lighthouse de DevTools, desde la terminal o en CI con Lighthouse CI.
Úsalo cuando
Antes de publicar, para comparar versiones y para detectar regresiones en el pipeline. También es una buena lista de tareas para empezar.
Ten en cuenta
La puntuación no es lo que usa Google para posicionarte, sino los datos de campo. Varía entre ejecuciones, así que repite la prueba y usa una ventana de incógnito sin extensiones. Optimizar para la nota en lugar de para los usuarios es una trampa.
# Solo rendimiento, en móvil simulado, y abre el informe
npx lighthouse https://tienda.com --only-categories=performance --view
# Escritorio, en JSON, para guardarlo o compararlo con otra versión
npx lighthouse https://tienda.com --preset=desktop \
--output=json --output-path=informe.jsonChrome DevTools
El panel Performance, la limitación de red y CPU y el panel Coverage.
- Paneles clave:
- Performance, Network, Coverage
El panel Performance graba una carga o una interacción y la muestra en una línea de tiempo: peticiones de red, actividad del hilo principal, tareas largas marcadas en rojo, saltos de diseño y el momento del LCP. En las versiones recientes muestra además tus LCP, CLS e INP locales en cuanto lo abres, y puede compararlos con los datos de campo del CrUX.
Para ver tu web como la ven tus usuarios, usa la limitación (throttling): de red, para simular una conexión móvil lenta, y de CPU, para simular un procesador más modesto. Y el panel Coverage (abre el menú de comandos con Ctrl+Shift+P y escribe «Coverage») te dice qué porcentaje de cada archivo JavaScript y CSS se ha usado de verdad: lo que sobra es candidato a cargarse más tarde.
Úsalo cuando
Cuando ya sabes qué métrica falla y necesitas encontrar la causa exacta: qué función bloquea el hilo, qué petición llega tarde, qué elemento salta.
Ten en cuenta
Tu equipo es mucho más rápido que el de tus usuarios: limita siempre la CPU y la red. Y mide la versión de producción, no el servidor de desarrollo, que es más lento y no se parece a lo que publicas.
// Avisa de cada salto de diseño y de qué elementos se movieron
new PerformanceObserver((lista) => {
for (const salto of lista.getEntries()) {
if (salto.hadRecentInput) continue; // los que provoca el usuario no cuentan
console.log("CLS +", salto.value.toFixed(3), salto.sources?.map((s) => s.node));
}
}).observe({ type: "layout-shift", buffered: true });Pruébalo
Abre DevTools en cualquier web, ve al panel Performance, activa la limitación de CPU y de red y graba una recarga. Busca las tareas marcadas en rojo en el hilo principal: cada una es un momento en que la página no podía responder.
Interactivo
¿Qué herramienta para qué?
Activa o desactiva opciones para compararlas cara a cara.
| Característica | Lighthouse | PageSpeed Insights | DevTools |
|---|---|---|---|
| Tipo de datos | Laboratorio | Campo (CrUX) y laboratorio | Laboratorio |
| Dónde se ejecuta | Tu navegador, la terminal o CI | Servidores de Google | Tu navegador |
| Usuarios reales | No | Sí, si hay tráfico suficiente | No |
| INP | No en una carga: usa el TBT | Sí, en los datos de campo | Sí, el de tus propias interacciones |
| Ideal para | Auditar y evitar regresiones | Ver lo que ve Google | Encontrar la causa exacta |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
Al cargar la ficha de producto aparece un aviso de cookies en la parte de arriba que empuja todo el contenido hacia abajo.
Para recordar
- Las Core Web Vitals son LCP (≤ 2,5 s), INP (≤ 200 ms) y CLS (≤ 0,1), medidas en el percentil 75 de las visitas reales.
- INP sustituyó a FID en 2024 y mide cuánto tarda la página en reaccionar a cada interacción.
- Los datos de laboratorio sirven para diagnosticar; los de campo, como el CrUX, dicen la verdad y son los que usa Google.
- PageSpeed Insights junta CrUX y Lighthouse; DevTools encuentra la causa exacta;
web-vitalste da tu propio RUM. - Mide siempre con la CPU y la red limitadas y en la versión de producción.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.¿Qué métrica sustituyó a FID como Core Web Vital en 2024?
2.¿Qué significa que una página «aprueba» el LCP?
3.¿Por qué una prueba de Lighthouse sobre la carga de una página no da un valor de INP?
4.Tu Lighthouse sale en verde, pero los datos de campo están en rojo. ¿Qué es lo más probable?
5.¿Qué cambio evita que una imagen provoque un salto de diseño al cargarse?