Desde mayo 2021, Google utiliza Core Web Vitals como factor de ranking oficial. Pero la realidad es brutal: el 65% de las webs suspenden en al menos una métrica Core Web Vitals, perdiendo posiciones en Google sin entender por qué. Tu contenido puede ser excelente, tu SEO impecable, pero si tu LCP supera los 2.5 segundos, estás invisible.
Core Web Vitals mide la experiencia de usuario real: velocidad de carga percibida (LCP), interactividad (FID/INP), y estabilidad visual (CLS). No son métricas académicas, son datos de usuarios reales navegando tu web desde móviles 4G, ordenadores lentos, conexiones inestables.
En esta guía exhaustiva te voy a revelar exactamente cómo medir, diagnosticar y optimizar cada métrica Core Web Vitals. Estrategias técnicas probadas, ejemplos de código reales, y herramientas específicas. Todo lo que necesitas para pasar de suspender a obtener "good" en las tres métricas.
⚡ ¿Tu web suspende en Core Web Vitals?
Auditoría técnica gratuita de rendimiento y optimización Core Web Vitals.
Solicitar auditoría gratuita🎯 ¿Qué son Core Web Vitals?
Core Web Vitals son 3 métricas específicas que Google considera críticas para medir la experiencia de usuario en web:
Las 3 Métricas Core Web Vitals
1. LCP (Largest Contentful Paint) - Velocidad de Carga Percibida
- Qué mide: Tiempo hasta que el elemento visual más grande del viewport es visible
- Good: ≤ 2.5 segundos
- Needs Improvement: 2.5 - 4.0 segundos
- Poor: > 4.0 segundos
- Elementos medidos: Imágenes, videos, bloques de texto grandes, backgrounds
- Por qué importa: Usuarios perciben web como "cargada" cuando ven contenido principal
2. FID/INP (First Input Delay / Interaction to Next Paint) - Interactividad
- Qué mide: Tiempo desde primera interacción hasta que navegador responde
- Good (FID): ≤ 100ms
- Good (INP - nueva métrica 2024): ≤ 200ms
- Interacciones medidas: Clicks, taps, teclas presionadas
- Por qué importa: Web que no responde = frustración, abandono inmediato
- Nota: INP reemplazará FID en marzo 2024
3. CLS (Cumulative Layout Shift) - Estabilidad Visual
- Qué mide: Cambios inesperados de layout durante carga
- Good: ≤ 0.1
- Needs Improvement: 0.1 - 0.25
- Poor: > 0.25
- Causas comunes: Imágenes sin dimensiones, ads, fuentes web, contenido dinámico
- Por qué importa: Clicks accidentales, pérdida de lectura, frustración
Impacto en SEO y Negocio
Datos reales del impacto de Core Web Vitals:
- +25% CTR orgánico en webs que pasan de "poor" a "good" en todas las métricas
- -53% bounce rate cuando LCP mejora de 4s a 2s
- +15% conversiones mejorando CLS de 0.25 a 0.05
- Ranking: Con contenido y backlinks similares, CWV puede ser factor decisivo
- Mobile-first indexing: Métricas móviles son las que cuentan para ranking
"Ecommerce moda 850k visitas/mes. Suspendía LCP (3.8s) y CLS (0.32). Implementamos lazy loading correcto, optimizamos imágenes hero, añadimos dimensiones explícitas, diferimos JS terceros. 8 semanas después: LCP 2.1s, CLS 0.07. Resultado: +18% tráfico orgánico, +12% conversión, +€47k revenue/mes. Core Web Vitals no es vanidad, es negocio." - Caso real cliente
📊 Cómo Medir Core Web Vitals
Existen dos tipos de datos: Field Data (RUM - Real User Monitoring) y Lab Data (sintético).
Field Data: Usuarios Reales (Lo que Google Usa para Ranking)
1. Google Search Console (CRÍTICO)
Ruta: Search Console → Core Web Vitals → Informe Mobile/Desktop
- Datos de usuarios reales de Chrome (CrUX - Chrome User Experience Report)
- Agrupado por páginas similares
- Actualización: 28 días históricos
- Requiere mínimo volumen tráfico
- ESTA es la data que afecta tu ranking
2. PageSpeed Insights (PSI)
URL: pagespeed.web.dev
- Combina Field Data (CrUX si disponible) + Lab Data (Lighthouse)
- Field Data: últimos 28 días usuarios reales
- Clasificación: Good/Needs Improvement/Poor
- Datos móvil y desktop separados
3. CrUX Dashboard (BigQuery o Data Studio)
URL: g.co/chromeuxdash
- Dashboard personalizado con datos CrUX históricos
- Puedes ver evolución temporal
- Comparar con competencia
- Segmentar por tipo conexión, dispositivo
Lab Data: Tests Sintéticos (Diagnóstico)
1. Lighthouse (Chrome DevTools)
Cómo: Chrome DevTools → Lighthouse → Generar informe
- Test sintético en tu máquina
- Útil para desarrollo y debugging
- NO refleja experiencia usuarios reales
- Configuración: Mobile/Desktop, Throttling
2. WebPageTest
URL: webpagetest.org
- Tests desde ubicaciones y dispositivos reales
- Filmstrip visual de carga
- Waterfall detallado de recursos
- Configuración avanzada: velocidades conexión, repeat views
3. Chrome DevTools Performance
- Recording completo de carga
- Identifica Long Tasks (>50ms)
- Ve exactamente qué JS bloquea interactividad
- Esencial para debuggear FID/INP
⚠️ IMPORTANTE: Field Data vs Lab Data
- Field Data (CrUX): Afecta ranking. Usuarios reales, dispositivos/conexiones reales.
- Lab Data (Lighthouse): Diagnóstico. No afecta ranking. Útil para encontrar problemas.
- Discrepancias: Es NORMAL que Lighthouse diga "good" pero Search Console "poor" (o viceversa)
- Prioriza: Primero arregla Field Data. Lab Data es para debugging.
⚡ Cómo Optimizar LCP (Largest Contentful Paint)
Meta: ≤ 2.5 segundos en el 75% de visitas (datos Field/CrUX)
Identificar tu Elemento LCP
Primero necesitas saber QUÉ elemento es tu LCP:
// Chrome DevTools Console
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP element:', lastEntry.element);
console.log('LCP time:', lastEntry.renderTime || lastEntry.loadTime);
}).observe({type: 'largest-contentful-paint', buffered: true});
Común mente el LCP es:
- Imagen hero del header
- Banner principal
- Primer bloque de texto grande
- Imagen destacada de artículo
- Video hero
Optimización #1: Imágenes LCP
A) Usa fetchpriority="high" en imagen LCP
<img src="hero.jpg"
alt="..."
fetchpriority="high"
width="1200" height="600">
B) NO hagas lazy loading de imagen LCP
<!-- ❌ MAL: lazy load en hero/LCP -->
<img src="hero.jpg" loading="lazy">
<!-- ✅ BIEN: eager loading para LCP -->
<img src="hero.jpg" loading="eager" fetchpriority="high">
C) Preload imagen LCP crítica
<link rel="preload" as="image"
href="hero.jpg"
fetchpriority="high">
D) Optimiza el peso de la imagen
- Formato: WebP (o AVIF si soportas)
- Tamaño: Sirve dimensiones exactas necesarias
- Compresión: 80-85% calidad suele ser invisible
- Herramientas: Squoosh, ImageOptim, TinyPNG
E) Responsive images con srcset
<img src="hero-800.webp"
srcset="hero-400.webp 400w,
hero-800.webp 800w,
hero-1200.webp 1200w"
sizes="(max-width: 768px) 100vw, 1200px"
alt="..."
fetchpriority="high">
Optimización #2: CSS Render-Blocking
A) Inline CSS crítico
<style>
/* CSS crítico para above-the-fold inline aquí */
.hero { display: block; ... }
</style>
<!-- CSS no-crítico diferido -->
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">
B) Elimina CSS no usado
- Herramienta: Coverage tab Chrome DevTools
- PurgeCSS: Automático con Tailwind/frameworks
- Critical CSS: Genera automático con Critical, Critters
Optimización #3: Fuentes Web
A) Preload fuentes críticas
<link rel="preload" as="font" type="font/woff2"
href="font.woff2" crossorigin>
B) Font-display: swap o optional
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: swap; /* o optional */
}
Optimización #4: Server/Hosting
- TTFB ≤ 600ms: Tiempo First Byte afecta LCP directamente
- CDN: Sirve assets desde servidores cercanos usuarios
- HTTP/2 o HTTP/3: Multiplexing mejora carga paralela
- Compresión: Gzip o Brotli para HTML/CSS/JS
- Cache headers: Evita re-descargas innecesarias
Optimización #5: JavaScript Blocking
A) Defer scripts no-críticos
<script src="analytics.js" defer></script>
<script src="third-party.js" defer></script>
B) Async para scripts independientes
<script src="ads.js" async></script>
C) Carga terceros después de evento
// Cargar scripts terceros después de LCP
window.addEventListener('load', () => {
// Google Analytics, pixels, etc aquí
});
🖱️ Cómo Optimizar FID / INP (Interactividad)
Meta FID: ≤ 100ms | Meta INP: ≤ 200ms
¿Qué es un Long Task?
Cualquier tarea JavaScript que bloquea main thread >50ms. Durante un Long Task, la web NO responde a interacciones usuario.
Identificar Long Tasks
Chrome DevTools Performance
- DevTools → Performance → Record
- Recarga página
- Busca barras rojas (Long Tasks)
- Click en Long Task → ve qué función causa el bloqueo
Optimización #1: Code Splitting
No cargues todo el JavaScript upfront. Split por rutas/componentes.
React/Next.js:
// Dynamic import
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <p>Loading...</p>
});
// Route-based splitting (automático en Next.js)
// pages/dashboard.js solo carga cuando visitas /dashboard
Webpack:
// webpack.config.js
optimization: {
splitChunks: {
chunks: 'all',
}
}
Optimización #2: Defer Scripts Terceros
Google Analytics, pixels, chats, ads suelen ser los peores offenders.
// Cargar después de interacción usuario o timeout
let thirdPartyLoaded = false;
const loadThirdParty = () => {
if (thirdPartyLoaded) return;
thirdPartyLoaded = true;
// Google Analytics
const script = document.createElement('script');
script.src = 'https://www.googletagmanager.com/gtag/js?id=GA_ID';
script.async = true;
document.head.appendChild(script);
};
// Cargar en primera interacción o después de 3s
['mousedown', 'touchstart', 'keydown'].forEach(event => {
window.addEventListener(event, loadThirdParty, {once: true});
});
setTimeout(loadThirdParty, 3000);
Optimización #3: Web Workers
Mueve procesamiento pesado fuera del main thread.
// worker.js
self.addEventListener('message', (e) => {
const result = heavyCalculation(e.data);
self.postMessage(result);
});
// main.js
const worker = new Worker('worker.js');
worker.postMessage(data);
worker.addEventListener('message', (e) => {
console.log('Result:', e.data);
});
Optimización #4: Debounce/Throttle Eventos
// Throttle scroll events
let ticking = false;
window.addEventListener('scroll', () => {
if (!ticking) {
window.requestAnimationFrame(() => {
handleScroll();
ticking = false;
});
ticking = true;
}
});
Optimización #5: Elimina JavaScript No Usado
- Coverage tab: Chrome DevTools → Coverage
- Tree shaking: Build tools modernos eliminan código muerto
- Audit libraries: ¿Realmente necesitas jQuery? ¿Toda librería X?
📐 Cómo Optimizar CLS (Cumulative Layout Shift)
Meta: ≤ 0.1 (sin unidades)
Causas Comunes de CLS
- Imágenes/videos sin dimensiones explícitas
- Ads, embeds, iframes sin espacio reservado
- Fuentes web causando FOIT/FOUT
- Contenido dinámico insertado arriba de contenido existente
- Animaciones CSS que cambian layout
Identificar Causas de CLS
// Chrome DevTools Console
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
console.log('Layout shift:', entry.value);
console.log('Affected elements:', entry.sources);
}
}
}).observe({type: 'layout-shift', buffered: true});
Optimización #1: Dimensiones Explícitas en Imágenes
<!-- ❌ MAL: sin width/height -->
<img src="image.jpg" alt="...">
<!-- ✅ BIEN: dimensiones explícitas -->
<img src="image.jpg" alt="..." width="800" height="600">
<!-- ✅ MEJOR: aspect-ratio CSS -->
<img src="image.jpg" alt="..." style="aspect-ratio: 16/9; width: 100%; height: auto;">
Optimización #2: Reserva Espacio para Ads/Embeds
<!-- Container con min-height para ad -->
<div class="ad-container" style="min-height: 250px;">
<!-- Ad code aquí -->
</div>
<!-- O con aspect-ratio -->
<div style="aspect-ratio: 16/9; background: #f0f0f0;">
<iframe src="youtube-embed" width="100%" height="100%"></iframe>
</div>
Optimización #3: Font-display para Fuentes Web
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2');
font-display: optional; /* Usa fallback si fuente no lista */
}
Optimización #4: Evita Insertar Contenido Arriba
// ❌ MAL: insertar banner arriba desplaza todo
document.body.insertBefore(banner, document.body.firstChild);
// ✅ BIEN: reserva espacio con min-height o placeholder
<div id="banner-placeholder" style="min-height: 80px;"></div>
Optimización #5: Anima transform/opacity (No layout properties)
/* ❌ MAL: animar width/height causa layout shift */
.element {
transition: width 0.3s;
}
/* ✅ BIEN: animar transform no causa reflow */
.element {
transition: transform 0.3s;
}
.element:hover {
transform: scale(1.1);
}
Optimización #6: Preload Fuentes Críticas
<link rel="preload" as="font" type="font/woff2"
href="font.woff2" crossorigin>
🔧 Herramientas de Monitoreo Continuo
1. Google Search Console
- Monitoreo automático Field Data
- Alertas cuando páginas empeoran
- Grouping por patrón URL
- Revisar: Semanalmente
2. PageSpeed Insights API
Automatiza tests PSI en tu CI/CD:
// Node.js ejemplo
const psi = require('psi');
const result = await psi('https://example.com', {
strategy: 'mobile'
});
console.log('LCP:', result.data.loadingExperience.metrics.LARGEST_CONTENTFUL_PAINT_MS);
3. Web Vitals JavaScript Library
Mide CWV de usuarios reales y envía a analytics:
import {getCLS, getFID, getLCP} from 'web-vitals';
function sendToAnalytics({name, value, id}) {
ga('send', 'event', {
eventCategory: 'Web Vitals',
eventAction: name,
eventValue: Math.round(value),
eventLabel: id,
nonInteraction: true,
});
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);
4. Lighthouse CI
Tests automáticos en cada deploy:
// .github/workflows/lighthouse-ci.yml
- name: Run Lighthouse CI
run: |
npm install -g @lhci/cli
lhci autorun
5. Real User Monitoring (RUM) Tools
- SpeedCurve: Monitoreo continuo RUM + sintético
- Cloudflare Web Analytics: Gratis, privacy-first
- New Relic Browser: RUM con detalles técnicos
- Sentry Performance: Integrado con error tracking
⚠️ Errores Comunes Optimizando Core Web Vitals
Error #1: Solo Optimizar Lab Data
❌ Lighthouse dice "good" pero Search Console muestra "poor"
✅ Prioriza Field Data (CrUX). Lab es diagnóstico, Field afecta ranking.
Error #2: Lazy Load de Imagen LCP
❌ <img src="hero.jpg" loading="lazy">
✅ <img src="hero.jpg" loading="eager" fetchpriority="high">
Error #3: Imágenes Sin Dimensiones
❌ <img src="image.jpg">
✅ <img src="image.jpg" width="800" height="600">
Error #4: Scripts Terceros Bloqueantes
❌ <script src="analytics.js"></script> en <head>
✅ <script src="analytics.js" defer></script> o cargar post-load
Error #5: No Monitorear Después de Optimizar
❌ Optimizas una vez, nunca revisas
✅ Monitoreo continuo (GSC, RUM tools, alertas)
Error #6: Optimizar Solo Homepage
❌ Solo optimizas home, resto suspende
✅ Optimiza templates completos (artículos, categorías, productos)
✅ Checklist Core Web Vitals
LCP (≤ 2.5s)
- ☐ Identifica elemento LCP (PerformanceObserver)
- ☐ Imagen LCP: fetchpriority="high", loading="eager"
- ☐ Imagen LCP: formato WebP, tamaño optimizado
- ☐ Preload recursos críticos (fuentes, imágenes)
- ☐ Inline CSS crítico, defer CSS no-crítico
- ☐ TTFB ≤ 600ms (hosting rápido, CDN)
- ☐ Defer/async scripts no-críticos
- ☐ Elimina CSS/JS no usado
FID/INP (≤ 100ms / ≤ 200ms)
- ☐ Identifica Long Tasks (Performance tab)
- ☐ Code splitting (route-based, component-based)
- ☐ Defer scripts terceros (analytics, ads, chat)
- ☐ Web Workers para cálculos pesados
- ☐ Throttle/debounce event handlers
- ☐ Elimina JavaScript no usado
- ☐ Reduce tamaño bundles JS (tree shaking)
CLS (≤ 0.1)
- ☐ Width + height en TODAS las imágenes
- ☐ Aspect-ratio CSS para responsive
- ☐ Reserva espacio para ads/embeds (min-height)
- ☐ font-display: swap/optional
- ☐ Preload fuentes críticas
- ☐ No insertes contenido arriba sin espacio reservado
- ☐ Anima transform/opacity (NO width/height/top/left)
Monitoreo
- ☐ Google Search Console Core Web Vitals (semanal)
- ☐ PageSpeed Insights (test manual)
- ☐ RUM implementado (web-vitals library + analytics)
- ☐ Lighthouse CI en pipeline
- ☐ Alertas configuradas para regresiones
🚀 Conclusión: Core Web Vitals es Inversión, No Gasto
Core Web Vitals no es optimización académica. Es factor de ranking oficial desde mayo 2021, y más importante: afecta directamente bounce rate, conversiones, y revenue. Una web con LCP 1.8s vs 4.2s no solo rankea mejor, convierte 2-3x más.
La clave no es conseguir "good" una vez. Es monitoreo continuo, porque cada feature nueva, cada script tercero, cada imagen mal optimizada puede degradar tus métricas. Implementa RUM, configura alertas, y trata CWV como KPI de negocio.
Mientras tu competencia sigue suspendiendo (65% de webs), tú pasas a "good" en las 3 métricas y capturas el tráfico, conversiones y revenue que ellos están perdiendo.
¿Tu Web Suspende en Core Web Vitals?
Auditoría técnica completa de rendimiento y optimización Core Web Vitals. Identificamos exactamente qué está afectando tus métricas y cómo arreglarlo.
- ✅ Análisis Field Data (CrUX real)
- ✅ Identificación elementos LCP problemáticos
- ✅ Análisis Long Tasks y scripts bloqueantes
- ✅ Detección causas CLS específicas
- ✅ Plan acción priorizado
- ✅ Implementación técnica si necesitas
- ✅ Monitoreo post-optimización