Otimizar imagens no Next.js
O next/image resolve boa parte do trabalho, mas seus valores padrão nem sempre são os melhores. Estas são as configurações que fazem diferença.
O que o next/image faz por você
O componente Image do Next.js gera automaticamente:
- Um
srcsetcom várias larguras da imagem. - Conversão para formatos modernos conforme o navegador (cabeçalho
Accept). loading="lazy"por padrão.- Atributos
widtheheightpara evitar CLS.
As imagens são otimizadas sob demanda no servidor (ou na plataforma de deploy) e armazenadas em cache.
Ative o AVIF
Por padrão, o Next.js só serve WebP. Para servir AVIF aos navegadores que o suportam, adicione o formato no next.config:
// next.config.js
module.exports = {
images: {
formats: ["image/avif", "image/webp"],
},
};
A ordem importa: é escolhido o primeiro formato aceito pelo navegador. O AVIF demora mais para ser gerado na primeira vez, mas depois é servido do cache.
A imagem principal: preload e prioridade
O next/image aplica lazy loading a todas as imagens, a menos que você indique o contrário. Para a imagem LCP:
<Image src={hero} alt="…" priority sizes="100vw" />
Nas versões mais recentes, a propriedade preload (ou fetchPriority="high" junto com loading="eager") cumpre a mesma função que priority. Confira a documentação da sua versão: a ideia é sempre a mesma, desativar o lazy e pré-carregar a imagem principal. Mais contexto em como melhorar o LCP.
sizes: a configuração mais esquecida
Sem sizes, o Next.js gera um srcset com descritores de densidade (1x, 2x) baseados no width que você indicar. Com sizes, ele gera descritores de largura e o navegador consegue escolher muito melhor:
<Image
src="/blog/capa.jpg"
alt="…"
width={1600}
height={900}
sizes="(min-width: 1024px) 768px, 100vw"
/>
Se você usa fill (a imagem ocupa o contêiner), o sizes é praticamente obrigatório; caso contrário, o navegador assume 100vw e baixa imagens grandes demais em layouts de colunas. Para calcular o valor certo a partir do seu layout, use o gerador de srcset.
Qualidade
O valor padrão é 75. As versões recentes exigem declarar em images.qualities as qualidades permitidas se você usar outras. Para fotografia, 70-80 costuma bastar; para imagens de produto, talvez 85.
Otimizar no servidor ou antes do build?
A otimização sob demanda tem vantagens (variantes automáticas), mas também custos:
- Primeira requisição lenta: cada combinação de tamanho e formato é gerada na primeira vez que alguém a pede.
- Custo ou limites da plataforma: alguns provedores cobram ou limitam as transformações de imagem.
- Imagens estáticas pesadas no repositório: se você sobe fotos de 8 MB, o build e o repositório crescem.
Uma estratégia sensata:
- Otimize os originais antes de adicioná-los ao projeto. Redimensione para um máximo razoável (por exemplo 2560 px) e comprima com o ImageZap. O repositório fica leve e o next/image trabalha sobre arquivos menores.
- Para sites estáticos (
output: "export") sem servidor de imagens, gere você mesmo as variantes AVIF/WebP e use<picture>diretamente ouunoptimized.
Imagens remotas
Para imagens de um CMS ou CDN externo, declare os domínios em images.remotePatterns. Se a CDN já otimiza e serve AVIF, você pode usar um loader personalizado para que o Next.js gere as URLs da CDN em vez de reotimizar.
Checklist
formats: ["image/avif", "image/webp"]na configuração.- A imagem LCP com
priority(oupreload) e sem lazy. sizesem todas as imagens responsivas e comfill.- Originais redimensionados antes de entrar no repositório.
altdescritivo em cada imagem.
Perguntas frequentes
O next/image funciona com exportação estática?
A otimização integrada precisa de um servidor. Com output: "export" você deve usar unoptimized ou um loader externo.
Por que minhas imagens demoram na primeira vez?
Porque estão sendo geradas. As requisições seguintes saem do cache.
Devo usar next/image para SVG?
Não acrescenta nada: SVGs não são otimizados como bitmaps. Use um <img> normal ou o SVG inline, de preferência depois de passá-lo pelo otimizador de SVG.
Posso usar os arquivos gerados pelo ImageZap com next/image?
Sim. Você pode importar os AVIF ou WebP diretamente ou usar o código JSX gerado com <picture> se preferir controlar os formatos.