Melhores Práticas de Otimização de Imagens no Nuxt cover image

Melhores Práticas de Otimização de Imagens no Nuxt

Imagens costumam ser os maiores recursos de um site Nuxt. Um banner principal, uma galeria de produtos ou a capa de um artigo pode pesar mais do que todo o bundle de JavaScript. A boa notícia é que o Nuxt oferece um conjunto objetivo de ferramentas para resolver isso sem transformar cada página em um pipeline customizado de imagens.

O módulo @nuxt/image encapsula padrões consolidados de otimização nos componentes <NuxtImg> e <NuxtPicture>. Usados com consistência, eles entregam sources responsivos, formatos modernos, lazy loading e integração com providers — com pouco ruído no template. O objetivo não é a perfeição no primeiro dia. É parar de enviar JPEGs em resolução total para viewports mobile.

Comece pelo módulo, não por URLs manuais

Instale e habilite o módulo na configuração do Nuxt, depois substitua tags <img> cruas nas views mais sensíveis a performance: heroes da home, cards de listagem e cabeçalhos de artigos. Ícones decorativos e assets pequenos de interface podem continuar como SVG ou gráficos inline quando isso já funciona bem.

Um erro comum é espalhar <NuxtImg> por todo o projeto e ainda assim passar arquivos enormes a partir de /public. A otimização ajuda, mas origem ruim ainda gera trabalho desnecessário no provider e carregamentos iniciais mais lentos. Exporte originais em tamanhos razoáveis e deixe o módulo gerar as variantes.

Escolha o componente certo

<NuxtImg> é a escolha padrão na maioria dos casos. Ele renderiza um <img> otimizado com defaults sensatos para lazy loading e dimensionamento responsivo. Use em thumbnails, avatares, imagens de conteúdo e cards.

<NuxtPicture> faz mais sentido quando você precisa de art direction ou fallbacks de formato. Ele gera um elemento <picture> com múltiplas tags <source>, útil para heroes com recortes diferentes no mobile e desktop, ou quando você quer AVIF com fallback para WebP e JPEG.

  • NuxtImg: imagens simples de conteúdo, listas, posts de blog
  • NuxtPicture: heroes, banners, recortes responsivos
  • Imagens de fundo: prefira markup real quando possível; backgrounds em CSS são mais difíceis de lazy load e não têm comportamento responsivo nativo

Defina dimensões explícitas

Sempre informe width e height, ou uma estratégia de sizes bem definida. Isso evita layout shift, ajuda o navegador a reservar espaço antes do carregamento e dá ao otimizador um alvo claro.

Para imagens de tamanho fixo na interface, use dimensões exatas:

<NuxtImg
  src="/images/author.jpg"
  width="64"
  height="64"
  alt="Retrato do autor"
  format="webp"
/>

Em layouts fluidos, defina a largura da imagem em cada breakpoint com sizes. Essa é uma das mudanças de maior impacto:

<NuxtImg
  src="/images/article-cover.jpg"
  width="1200"
  height="630"
  sizes="sm:100vw md:50vw lg:800px"
  alt="Capa do artigo"
/>

Sem sizes, o navegador pode baixar um arquivo maior do que o necessário mesmo quando a largura renderizada é pequena. Isso desperdiça banda e atrasa o Largest Contentful Paint.

Use formatos modernos com critério

Deixe o módulo servir WebP ou AVIF quando o provider suportar. Na maioria dos projetos, format="webp" é um default seguro. AVIF pode economizar mais bytes, mas teste com seu tráfego real e tipos de imagem antes de habilitar globalmente.

Se você precisa de compatibilidade máxima sem depender da negociação do provider, <NuxtPicture> com sources em camadas é o padrão mais confiável:

<NuxtPicture
  src="/images/hero.jpg"
  width="1600"
  height="900"
  sizes="100vw"
  :formats="['avif', 'webp']"
  alt="Hero do produto"
/>

Não converta todo asset no automático. Logos, screenshots com texto fino e PNGs já otimizados podem não ganhar muito. Meça antes de padronizar uma regra de formato em todo o app.

Lazy load por padrão, eager load com intenção

O @nuxt/image faz lazy load por padrão, que é o comportamento certo abaixo da dobra. Para a maior imagem acima da dobra — em geral o hero ou a capa do artigo — use loading="eager" e considere fetchpriority="high" para o navegador iniciar o fetch cedo.

Seja seletivo. Marcar dez imagens como eager anula o propósito. Um candidato forte por rota costuma ser suficiente.

Escolha um provider alinhado ao deploy

O módulo suporta vários providers: local/IPX para desenvolvimento e deploys simples, além de opções com CDN como Cloudinary, ImageKit, Vercel e outras. A escolha deve seguir onde as imagens realmente vivem em produção.

  • IPX: ótimo para dev local, apps pequenos e setups self-hosted
  • Cloudinary / ImageKit: bom encaixe para produtos com muito volume de mídia e fluxos de DAM
  • Providers nativos de CDN: ideais quando as imagens já estão na mesma plataforma do deploy

Configure domínios e padrões remotos com cuidado. Se você carrega imagens de um CMS ou bucket S3, libere apenas os hosts confiáveis. Isso mantém o otimizador útil sem transformar o app em um proxy aberto.

Otimize imagens de CMS e remotas

Muitos apps Nuxt não guardam toda a mídia em /public. Eles buscam de Contentful, Strapi, Sanity ou uma API Laravel. Nesses casos, passe a URL remota direto para <NuxtImg> e deixe o provider transformar.

Quando o CMS já entrega variantes responsivas, evite otimização dupla. Ou o CMS cuida do redimensionamento e o Nuxt Image fica responsável por formato e lazy loading, ou você centraliza as transformações em um único lugar. Fazer os dois costuma adicionar complexidade sem ganho real.

Preserve acessibilidade e SEO

Trabalho de performance não pode sacrificar semântica. Toda imagem com significado precisa de um alt descritivo. Imagens decorativas devem usar alt vazio ou ser tratadas como conteúdo apenas visual, sem poluir a leitura por leitores de tela.

Para imagens que sustentam ranqueamento e compartilhamento social, mantenha URLs estáveis quando possível e use dimensões adequadas para assets de Open Graph. Otimização melhora a experiência; metadados corretos ainda impulsionam descoberta.

Meça o que o usuário realmente recebe

Confiança só no build não basta. Verifique Lighthouse, WebPageTest e seus Core Web Vitals com dados de analytics. Compare bytes transferidos antes e depois de trocar tags <img> em uma rota de alto tráfego.

Observe LCP, CLS e o peso total de imagens. Se o LCP melhora mas o CLS piora, provavelmente faltaram width e height. Se os bytes caem mas o LCP não muda, o hero pode estar carregando tarde ou com prioridade errada.

Um plano prático de adoção

Você não precisa de um refactor massivo. Comece pelos três templates com mais tráfego. Substitua as maiores imagens por <NuxtImg> ou <NuxtPicture>, adicione sizes, defina dimensões explícitas e configure o provider de produção. Publique, meça e só então documente regras curtas para o time.

Usado com consistência, a otimização de imagens no Nuxt é menos sobre configuração sofisticada e mais sobre hábitos disciplinados: componente certo, dimensões certas, estratégia de carregamento certa e um provider que combine com sua stack. É isso que transforma imagens de um incêndio recorrente de performance em um problema resolvido.