Entrega de Imagens na Era Edge — Design de CDN 2025

Publicado: 22 de set. de 2025 · Tempo de leitura: 4 min · Pela equipe editorial da Unified Image Tools

Para crescer o tráfego orgânico, entregar imagens rápido não é opcional. Este guia organiza os pontos de design de edge/CDN por caso de uso e traz uma checklist para evitar armadilhas em produção.

Fundamentos de um Image CDN

  1. Defina as unidades de transformação (origem vs variantes transformadas)
  2. Defina a cache key (URL, Accept, Accept-Encoding, DPR etc.)
  3. Expiração e invalidação (fingerprint, Cache-Control, stale-while-revalidate)
  4. Coordene com imagens responsivas (srcset/sizes corretos)

Links internos: noções de srcset, entrega focada em INP, priority hints e preload

Cabeçalhos HTTP na prática

Cache-Control: public, max-age=86400, stale-while-revalidate=259200
Vary: Accept, DPR
Accept-Ranges: bytes
Timing-Allow-Origin: *
  • Use Vary: Accept para negociar AVIF/WebP/JPEG
  • Se adicionar Vary: DPR, gere/faça cache de variantes por DPR no servidor
  • Em SSG/ISR, versionar a URL é o mais seguro (ex.: hero-640.avif?v=20250922)

Priority Hints / Early Hints

<!-- Para candidatos a LCP -->
<link rel="preload" as="image" href="/images/hero-1200.avif" imagesrcset="..." imagesizes="(min-width: 1024px) 1200px, 90vw" fetchpriority="high" />
  • Não marque tudo como alta prioridade (pode competir com o orçamento de CLS)
  • Se disponível, envie 103 Early Hints para fazer preconnect/preload mais cedo

Separe transformações no edge e na origem

  • Edge: negociação frequente de formato/largura/qualidade (AVIF/WebP)
  • Origem: etapas de maior custo e de fidelidade crítica (edição de metadados, ICC, composição com alpha)

Ferramentas: Conversor de formato, Compressão em lote, Gerador de placeholder

Armadilhas clássicas

  • Vary configurado mas a CDN não faz cache (duplicidade de configuração)
  • Retornar AVIF para clientes antigos sem Accept: image/avif → índices quebrados
  • Dupla transformação por serviço otimizador e CDN do app → perda de qualidade

Checklist (persistente)

  • [ ] Imagens LCP: fetchpriority e sizes corretos
  • [ ] Cache keys por versionamento de URL ou Vary
  • [ ] Fallback seguro (JPEG) em erros de transformação
  • [ ] alt + dados estruturados para SEO de imagens

Detalhes da cache key

  • Chaves sugeridas: URL + Accept + DPR + Width + Quality
  • Normalize w/q em funções de edge (ex.: 320/480/640/…)
  • Exemplo de cabeçalhos de resposta:
Cache-Control: public, max-age=604800, stale-while-revalidate=2592000
Vary: Accept, DPR
CDN-Cache-Status: HIT

Estratégia de fallback AVIF/WebP

  1. Escolha AVIF por Accept; depois WebP; fallback para JPEG
  2. Fallback no servidor em timeouts/erros → JPEG
  3. No cliente, <picture> com type ajuda o navegador a escolher (use srcset type para tornar a negociação explícita)
<picture>
  <source type="image/avif" srcset="hero.avif 1x, hero@2x.avif 2x" />
  <source type="image/webp" srcset="hero.webp 1x, hero@2x.webp 2x" />
  <img src="hero.jpg" alt="..." width="1200" height="630" />
</picture>

Normalizando resize sob demanda

  • Conjunto fixo de larguras ligado a sizes: 320/480/640/768/960/1200/1600/2000
  • Arredonde w de entrada para o mais próximo e evite fragmentação do cache
  • q por uso: miniaturas 60/fotos 70/UI 80

Segurança e abuso

  • URLs assinadas para impedir transformações sem limites (w/h/q/fmt assinados)
  • Rate limit e disjuntor (circuit breaker) em falhas
  • Bloqueie filtros pesados que possam causar DoS de CPU

Observabilidade / controle de custo

  • Log: URL, fmt, w, q, dpr, cacheStatus, genTime, size
  • Painéis: taxa de acerto por formato, tamanhos medianos, p95 de geração
  • Custo: pré‑gerar tamanhos “quentes”; TTL longo para aliviar a origem

Função de edge (pseudo)

export default async function handle(req) {
  const u = new URL(req.url)
  const w = normalizeWidth(u.searchParams.get('w'))
  const q = normalizeQuality(u.searchParams.get('q'))
  const fmt = negotiate(req.headers.get('Accept'))
  const key = `${u.pathname}?w=${w}&q=${q}&fmt=${fmt}`
  const cached = await caches.default.match(key)
  if (cached) return cached
  const out = await transform(u.pathname, { w, q, fmt })
  return new Response(out.body, { headers: responseHeaders({ fmt, w, q }) })
}

Troubleshooting

  • Sem imagem em browsers antigos → corrija a negociação por Accept ou use <source type>
  • Geração lenta → reduza o conjunto de larguras, presete qualidade, evite dupla re‑encode
  • Inconsistência de qualidade → fixe q por uso; use effort moderado em AVIF

FAQ

P. WebP/AVIF devem sempre ser preferidos?

R. Equilibre compatibilidade e custo de geração. Em superfícies de marca, JPEG ainda pode vencer.

P. Mais eixos em Vary não reduzem o cache hit?

R. Normalize largura/qualidade para controlar a fragmentação. Limite DPR onde realmente importa.

Resumo

“Chaves de cache corretas” e “otimização limitada aos candidatos a LCP” é o caminho mais curto para melhorar velocidade percebida e tráfego orgânico. Comece pelas imagens hero e faça testes A/B pequenos.