Optimización de Imágenes
Reglas
- Usa
next/image para todas las imágenes en Next.js — optimización automática, carga diferida, conjuntos de fuentes responsivos
- Siempre establece
width y height o usa fill con un contenedor dimensionado — evita el desplazamiento de diseño (CLS)
- Marcador de posición borroso: genera
blurDataURL en tiempo de compilación/subida con plaiceholder o usa placeholder="blur" para importaciones estáticas
- Imágenes remotas: configura
remotePatterns en next.config.js — lista blanca de dominios CDN
- Flujo de subida: cliente → URL prefirmada (S3/R2/Supabase Storage) → subida directa → almacenar URL en la base de datos
- Redimensionar al subir: usa
sharp del lado del servidor para crear múltiples tamaños (miniatura, mediano, completo) — no sirvas los originales
- Formatos: sirve WebP/AVIF mediante la auto-formato de
next/image — recurre a JPEG para compatibilidad
- Entrega CDN: almacena originales en almacenamiento de objetos (S3, R2), sirve a través de CDN (CloudFront, Cloudflare) con cabeceras de caché
- Validación de tamaño máximo de archivo: verifica en el cliente (antes de subir) y en el servidor (antes de procesar) — límite típico de 5-10MB
Patrones
import Image from "next/image";
<Image
src="/hero.jpg"
alt="Imagen principal"
width={1200}
height={630}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQ..."
priority // sobre el pliegue
/>
<div className="relative aspect-video">
<Image src={url} alt={alt} fill className="object-cover" sizes="(max-width: 768px) 100vw, 50vw" />
</div>
import sharp from "sharp";
async function processUpload(buffer: Buffer) {
const thumbnail = await sharp(buffer).resize(200, 200, { fit: "cover" }).webp({ quality: 80 }).toBuffer();
const medium = await sharp(buffer).resize(800).webp({ quality: 85 }).toBuffer();
const full = await sharp(buffer).resize(1920).webp({ quality: 90 }).toBuffer();
return { thumbnail, medium, full };
}
Evitar
- Usar etiquetas
<img> en Next.js — pierdes optimización automática, carga diferida y conversión de formato
- Faltar la propiedad
sizes en imágenes responsivas — el navegador no puede elegir el tamaño de srcset correcto
- Servir originales sin redimensionar — una foto de 5MB mostrada a 400px es un desperdicio
- Omitir la validación del tipo de archivo — verifica el tipo MIME en el servidor, no solo la extensión del archivo