El 90% de Tus Páginas Next.js Fracan en Core Web Vitals Por Imágenes Mal Optimizadas
Si tu LCP supera los 2,5 segundos, hay un 90% de probabilidad de que el culpable sea una imagen mal configurada.
Pero no por la razón que crees.
La mayoría asume que el problema es la compresión o el formato. WebP, AVIF, compresión con sharp. Soluciones superficiales que ignoran el verdadero fallo arquitectónico.
El problema real no es el peso del archivo. Es que tu estrategia de carga de imágenes está acoplada al render principal, propagando fallos en cascada y bloqueando el Largest Contentful Paint.
Los remote patterns mal configurados, la ausencia de priority hints, y el sizes attribute genérico están destruyendo tus métricas de forma silenciosa.
Voy a mostrarte cómo el componente Image de Next.js, configurado con remote patterns específicos y estrategias responsivas conscientes del viewport, puede mejorar tu LCP un 40% y reducir CLS a casi cero.
El Problema: Arquitectura de Carga Acoplada
Vuestra aplicación Next.js tiene 47 imágenes.
Tres vienen de tu CMS. Otras dos de un CDN de thumbnails. El resto son estáticas en public/. Algunas aparecen above the fold. Otras tras tres scrolls.
Ninguna tiene priority. Todas usan sizing="auto" sin configuración. Los remote patterns están en next.config.js como un bloque genérico que acepta todo.
Esto os suena. A todos.
El componente Image de Next.js hace optimización básica automáticamente. Conversión a WebP, redimensionamiento, lazy loading. Pero no toma decisiones sobre prioridad, sizes, ni remote patterns sin configuración explícita. Es una herramienta poderosa que necesita dirección, no un piloto automático.
Por Qué el Fallo en Cascada Ocurre Silenciosamente
Cuando el navegador encuentra 47 imágenes sin prioridad definida, aplica heurísticas internas que priorizan imágenes visibles en el viewport inicial. Pero sin metadata correcta, esa decisión es imprecisa. El resultado: recursos de baja prioridad se descargan primero, las imágenes above the fold esperan, y el LCP se desploma.
La arquitectura de carga acoplada significa que el fallo de una imagen — timeout, 404, formato no soportado — puede propagarse a otras. Si tu placeholder no mantiene dimensiones consistentes, cada fallo introduce layout shift. Tres fallos en cascada multiplican el CLS de forma no lineal.
❌ Lo que la mayoría hace:
- Usar
<img>nativo porque "es más simple" — renunciando a optimización server-side, conversión automática de formato, y resize responsivo - Configurar remotePatterns con dominios genéricos wildcard como
**/*.dominio.com— permitiendo acceso a cualquier path y creando vectors de ataque XSS - Ignorar priority en imágenes above the fold — el navegador asume que todas las imágenes tienen prioridad equivalente
- Omitir sizes attribute o ponerlo con valor fijo "100vw" — el navegador descarga imágenes del tamaño más grande posible, independientemente del espacio real
✅ Lo que funciona:
- Migrar cada
<img>a<Image>con configuración específica adaptada a su contexto en el layout - Definir remote patterns por dominio con restricciones de protocolo y pathname mínimas necesarias
- Marcar priority=true exclusivamente en imágenes que contribuyen directamente al LCP
- Calcular sizes dinámico basado en breakpoints reales del diseño, no valores arbitrarios
La diferencia entre ambos enfoques es la diferencia entre pasar Core Web Vitals con holgura y fallar sistemáticamente en todas las métricas de render. En aplicaciones reales, equipos que implementan esta arquitectura ven mejoras de LCP del 40% dentro de la primera semana.
Por Qué Fallan las Soluciones Superficiales
El concepto de arquitecturas desacopladas revela un principio transferible: cuando los estados están acoplados, los fallos se propagan en cascada. Aplicado a imágenes, cada imagen debe cargarse independientemente con su propio error boundary y loading state, sin afectar el render de otros componentes ni el layout general.
Una estrategia responsiva completa no es solo comprimir a WebP. Es coordinar cinco capas que operan independientemente:
- CDN y optimización en servidor — Next.js Image procesa en el Edge, sirviendo formatos modernos sin trabajo client-side
- Formato moderno — AVIF con fallback automático a WebP cuando el navegador no soporta el formato óptimo
- Breakpoints responsivos — sizes que reflejen el espacio real en cada viewport, evitando descarga de pixels innecesarios
- Priority loading — signals al navegador sobre qué cargar primero, acelerando el render del contenido crítico
- Error handling — fallback con blur placeholder que no desplace contenido, manteniendo CLS bajo control
Cada capa debe fallar independientemente sin afectar las demás. Si tu placeholder es un div vacío que colapsa al cargar la imagen, tu CLS sube. Si tu imagen above the fold no tiene priority, el navegador descarga 47 imágenes en paralelo y tu LCP se desploma.
La clave es entender que estas capas no son opciones independientes sino un sistema interdependiente. Omitir una comprometela gesamte estrategia.
El Error de Priorizar Conversión Rápida sobre Estrategia Completa
Equipos que migran imágenes a WebP rápidamente suelen ver mejoras marginales en Lighthouse que no se traducen en Core Web Vitals mejores en campo. La razón: están tratando síntomas (tamaño de archivo) cuando el problema es arquitectónico (cómo y cuándo se cargan las imágenes).
Implementar sizes attribute correctamente requiere analizar el diseño, identificar breakpoints reales, y calcular el espacio que ocupa cada imagen en cada breakpoint. No es trivial, pero el impacto es órdenes de magnitud mayor que cambiar formatos.
Similarmente, configurar remote patterns específicos por dominio requiere auditaring todos los orígenes de imágenes y documentar restricciones de pathname. Equipos que toman atajos aquí terminan con configuraciones permisivas que generan warnings en producción o bloquean imágenes legítimas.
El resultado de soluciones superficiales: métricas marginalmente mejores que no solucionan el problema de fondo y requieren trabajo adicional重复ido.
Configurar Remote Patterns Para Cada Dominio
El primer paso es auditar qué dominios estáis usando. CMS, CDNs, servicios de terceros. Cada uno necesita su propia configuración en next.config.js con las restricciones mínimas necesarias para funcionar.
Restricciones de Seguridad: Por Qué el Pathname Importa
El pathname no es solo configuración técnica. Cada wildcard adicional en el pathname es una superficie de ataque potencial. Si vuestro CMS tiene un endpoint de upload vulnerable, una configuración con pathname: '/**' permite que Next.js sirva imágenes desde ese endpoint si el dominio está en la lista.
Usad el mínimo pathname necesario. Si vuestro CDN sirve imágenes solo desde /images/, configurad /images/**. Si sirvéis avatares desde /uploads/avatars/, especificad exactamente ese path.
La configuración con wildcard en subdominios (*.midominio.es) tiene sentido cuando operáis en múltiples entornos — staging, production, preview — pero debéis asegurar que todos los subdominios son trusted y no contienen contenido user-generated sin sanitización.
Notad cómo incluso los dominios de staging tienen configuraciones separadas. Mezclar configuraciones de producción y staging puede llevar a servir imágenes de staging en producción si hay errores de configuración.
Implementar Priority y Sizes Correctamente
El atributo priority en el componente Image activa el preload del recurso en el head del documento. El navegador recibe esta señal y prioriza la descarga antes que otros recursos de menor prioridad. Esto marca la imagen como critical para el render del LCP.
Solo aplicadlo en imágenes above the fold que contribuyen directamente al Largest Contentful Paint. No en todas. Marcar 40 imágenes como priority diluye la señal y puede empeorar el rendimiento general, ya que el navegador intenta descargar todo simultáneamente.
El Proceso de Decisión para Priority
Identificad qué elementos constituyen el LCP en cada página:
- Hero images — típicamente el elemento más pesado y visible en la mitad superior de la página
- Logos en el header — si el texto del logo es parte del contenido principal
- Imágenes de productos above the fold — en e-commerce, la imagen principal del producto visible sin scroll
- Imagen de banner con texto — si el banner tiene importancia semántica
Las imágenes decorativas, thumbnails, e iconos rara vez contribuyen al LCP y deben mantener el lazy loading por defecto.
Sizes: La Variable Más Mal Interpretada
El sizes attribute es crítico y frecuentemente omitido o mal configurado. Le decís al navegador cuánto espacio ocupa la imagen en cada breakpoint. Sin esta información, el navegador asume 100vw y descarga imágenes sobredimensionadas para el espacio disponible.
La sintaxis de sizes es un media query seguido del width de la imagen en ese breakpoint:
Para el hero en el ejemplo anterior: 100vw en móvil (toda la pantalla), 80vw en tablet (80% del ancho), 1200px fijo en desktop (ancho máximo del contenedor).
Para thumbnails en grid de 3 columnas en móvil, 4 columnas en tablet, 6 en desktop:
Calcular esto correctamente puede mejorar LCP un 40% según datos de rendimiento en aplicaciones reales. El navegador toma decisiones de descarga basadas en esta información. Sin ella, asumirá el peor caso y descargará imágenes innecesariamente grandes.
El Patrón de las 5 Capas de Carga Independiente
He desarrollado un framework para estructurar la carga de imágenes en Next.js de forma que cada capa falle independientemente. Ningún fallo debe propagarse a otras capas ni afectar el render de contenido no relacionado.
Capa 1: CDN y Optimización Server-Side
Configurad Image domains con dominios trusted y usad Image Optimization API de Next.js. El servidor redimensiona y convierte automáticamente según el User Agent del cliente.
La combinación de deviceSizes e imageSizes define los breakpoints de redimensionamiento. deviceSizes se usa para imágenes de contenido (photos, heroes). imageSizes para imágenes pequeñas (iconos, avatares). Si vuestra imagen en móvil tiene 300px de ancho, Next.js servirá una imagen de 320px, optimizando para ese viewport específico.
Capa 2: Responsive Sizing con Breakpoints Reales
Cada breakpoint debe corresponderse con vuestro CSS real. No números arbitrarios. Si vuestro CSS tiene breakpoints en 768px y 1024px, el sizes attribute debe reflejar exactamente esos puntos.
Capa 3: Priority Loading Selectivo
Solo las imágenes que contribuyen al LCPget priority. Marcadlas explícitamente con una taxonomía documentada.
Este enfoque os permite documentar la decisión de priorización y auditar qué imágenes tienen priority en cada breakpoint.
Capa 4: Blur Placeholder con Desplazamiento Controlado
El placeholder blur no debe causar layout shift. Usad el contenedor con aspect-ratio o dimensiones fijas. El objetivo es que el espacio esté reservado antes de que la imagen cargue.
La clave: el wrapper define las dimensiones, no la imagen. Si la imagen falla en cargar o muestra el placeholder, el espacio ya está reservado.
Capa 5: Error Boundary por Imagen
Cada imagen debe tener su propio fallback sin afectar el resto de la UI. El error boundary captura fallos individuales y muestra un placeholder coherente con el diseño.
Este componente aisla el error y evita que fallos en imágenes individuales propaguen errores React o rompan la página.
Auditar y Monitorizar Métricas de Imagen
Configurad Lighthouse CI en vuestro pipeline de deploy para bloquear cambios que degraden métricas de imagen. El análisis preventivo es más efectivo que la corrección reactiva.
La configuración de numberOfRuns a 3 toma el promedio de tres ejecuciones, reduciendo variación por condiciones de red.
Usad WebPageTest para análisis detallado de waterfall de carga de imágenes. Identificad qué recursos bloquean el render y cuánto tiempo tardan. Las métricas de laboratorio (Lighthouse) son útiles para desarrollo, pero las métricas de campo (Chrome User Report, CrUX) reflejan la experiencia real de usuarios.
Checklist de Auditoría de Imágenes
Antes de cada release, verificad:
- [ ] Todas las imágenes above the fold tienen priority=true
- [ ] Ninguna imagen decorativa tiene priority (diluye la señal)
- [ ] sizes attribute refleja breakpoints reales del diseño
- [ ] remotePatterns tienen pathname restrictivo, no wildcards innecesarios
- [ ] Placeholders mantienen dimensiones consistentes (sin CLS)
- [ ] Error boundaries capturan fallos de carga sin romper la UI
- [ ] Lighthouse CI falla el build si LCP > 2500ms o CLS > 0.1
Resumen y Siguiente Paso
La optimización de imágenes en Next.js no es solo comprimir archivos. Es una estrategia arquitectónica de 5 capas que debe desacoplarse del render principal para evitar fallos en cascada.
Los remote patterns deben configurarse por dominio con restricciones mínimas necesarias. El sizes attribute debe reflejar breakpoints reales, no valores arbitrarios. Priority debe usarse selectivamente en elementos que contribuyen directamente al LCP. Los placeholders deben mantener dimensiones fixas para eliminar CLS.
Implementad las 5 capas del Patrón de Carga Independiente y monitorizad con Lighthouse CI en cada deploy. Automatizad la auditoría para que ningún cambio degrade las métricas accidentalmente.
Vuestra puntuación en Core Web Vitals mejorará. LCP bajo 2,5 segundos. CLS por debajo de 0,1. FID casi instantáneo.
El 90% de páginas que fallan en métricas lo hace por configuraciones genéricas y soluciones superficiales que tratan síntomas ignorando causas raíz. Vosotros vais a ser el 10% que optimiza con intención, implementando cada capa del framework con precisión consciente de las consecuencias.
Artículos relacionados
- Vercel Deployment Best Practices: The 5 Mistakes Tripling Your Costs
- Next.js en Producción: La Arquitectura que Separa los Proyectos que Escalan de los que Explotan
- Parallel Routes en Next.js: Cómo Construir Layouts con Estados de Carga Independientes
- Next.js 16: Las Features que el 90% de Developers Todavía No Entienden
- Server Components: El Error de Arquitectura que Anula el Rendimiento en Next.js 16
---
¿Quieres recibir contenido como este cada semana? Suscríbete a mi newsletter

