Otimização de Imagens
Regras
- Use
next/image para todas as imagens em Next.js — otimização automática, carregamento preguiçoso (lazy loading), conjuntos de srcset responsivos
- Sempre defina
width e height ou use fill com um container dimensionado — evita mudança de layout (CLS)
- Placeholder de desfoque: gere
blurDataURL no momento do build/upload com plaiceholder ou use placeholder="blur" para importações estáticas
- Imagens remotas: configure
remotePatterns em next.config.js — coloque os domínios do CDN na lista de permissões
- Fluxo de upload: cliente → URL pré-assinada (S3/R2/Supabase Storage) → upload direto → armazenar URL no banco de dados
- Redimensione no upload: use
sharp no servidor para criar múltiplos tamanhos (miniatura, médio, completo) — não sirva os originais
- Formatos: sirva WebP/AVIF via formatação automática do
next/image — use JPEG como fallback para compatibilidade
- Entrega via CDN: armazene originais em object storage (S3, R2), sirva através de CDN (CloudFront, Cloudflare) com cabeçalhos de cache
- Validação de tamanho máximo de arquivo: verifique no cliente (antes do upload) e no servidor (antes do processamento) — limite típico de 5-10MB
Padrões
import Image from "next/image";
<Image
src="/hero.jpg"
alt="Imagem hero"
width={1200}
height={630}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQ..."
priority // acima da dobra
/>
<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 };
}
Evite
- Usar tags
<img> em Next.js — perde otimização automática, carregamento preguiçoso e conversão de formato
- Faltar a prop
sizes em imagens responsivas — o navegador não consegue escolher o tamanho correto do srcset
- Servir originais sem redimensionamento — uma foto de 5MB exibida em 400px é desperdício
- Pular validação de tipo de arquivo — verifique o tipo MIME no servidor, não apenas a extensão do arquivo