Resource Hints em 2026: Guia Completo de preload, preconnect, prefetch, dns-prefetch e modulepreload
Resource Hints (preload, preconnect, prefetch, dns-prefetch, modulepreload) controlam o caminho crítico da rede e podem cortar centenas de ms do LCP. Guia atualizado para 2026 com exemplos, limites e como medir o ganho real.
Resource Hints são diretivas declarativas (<link rel="...">) que pedem ao navegador para iniciar antes da hora certas operações de rede: resolução DNS, handshake TCP/TLS, download de sub-recursos e até navegações futuras, antes que o parser HTML descubra a necessidade sozinho. Em 2026, o conjunto efetivo são cinco hints (dns-prefetch, preconnect, preload, modulepreload e prefetch) mais o atributo fetchpriority. Usados com cuidado, eles cortam centenas de milissegundos do LCP. Usados em excesso, saturam a conexão e pioram tudo.
dns-prefetch resolve apenas DNS (~20–120 ms); preconnect faz DNS + TCP + TLS (~100–500 ms economizados).
preload serve para recursos da página atual descobertos tarde pelo parser; prefetch serve para recursos de navegações futuras.
modulepreload faz fetch + parse + compile de módulos ES e suas dependências, ao contrário de preload as="script".
O atributo fetchpriority="high" (Baseline 2024) substitui muitos casos de preload para a imagem de LCP.
Pré-carregar tudo é o erro mais comum: a banda dos primeiros 14 KB do TCP é finita, e cada hint compete pela mesma fila.
Confirme cada hint no painel Network do DevTools com a coluna "Priority" e nos painéis do Lighthouse Performance Insights.
O que são resource hints e quando usá-los
Resource hints são instruções declarativas que o navegador interpreta enquanto o HTML é parseado. Em vez de esperar que o pré-carregador (preload scanner) descubra um <img>, uma fonte @font-face dentro de CSS, ou um import() dinâmico no JavaScript, você diz, de forma explícita, ao browser: "comece esse trabalho agora". Cada hint corresponde a uma fase distinta do pipeline de rede (da resolução DNS até o parse e compile de um módulo ES), e usar o hint errado para a fase certa não traz benefício mensurável.
O ganho real vem do caminho crítico do LCP. Num trace típico, a sequência para carregar a imagem hero é: parse HTML, encontrar CSS, baixar CSS, parsear CSS, descobrir background-image, DNS, TCP, TLS, request, resposta, decode, paint. Cada etapa adiciona latência sequencial. Os hints permitem paralelizar essas fases: enquanto o CSS ainda baixa, o DNS para o CDN da imagem já foi resolvido e a conexão TLS já está aberta. Para uma análise complementar das métricas que esses hints melhoram, dê uma olhada no nosso guia de LCP e os Core Web Vitals.
Em 2026, todos os cinco hints discutidos abaixo têm suporte universal nos navegadores baseados em Chromium, Firefox e Safari versão 17.2 ou superior. O HTML Living Standard documenta os tipos válidos de rel de forma normativa.
dns-prefetch: o hint mais barato
O dns-prefetch apenas dispara uma consulta DNS para o host indicado. Não abre socket, não negocia TLS. Só resolve o nome para um endereço IP e armazena em cache. Custa praticamente zero (um pacote UDP de aproximadamente 70 bytes em cada direção) e economiza, em média, entre 20 ms e 120 ms da próxima conexão para aquele host, dependendo da localização do resolver e do TTL.
<!-- Resolve o DNS de um CDN secundario antecipadamente -->
<link rel="dns-prefetch" href="https://cdn.terceiros.example">
<link rel="dns-prefetch" href="https://analytics.example.com">
Use dns-prefetch quando você sabe que um host vai ser contatado mais tarde no ciclo da página. Por exemplo: scripts de analytics carregados depois do load, anúncios diferidos, ou imagens de produto carregadas via IntersectionObserver. Para hosts críticos no caminho do LCP, prefira preconnect, que já inclui o DNS.
Limite prático: não passe de 8 a 10 entradas de dns-prefetch por página. O Chrome impõe um teto de conexões pendentes, e excesso de pré-resoluções desperdiça CPU do dispositivo (notavelmente em Android low-end). Audite com chrome://net-internals/#dns.
preconnect: DNS + TCP + TLS antecipados
O preconnect faz tudo o que dns-prefetch faz, e ainda completa o handshake TCP de três vias (1 RTT) e a negociação TLS (1 RTT com TLS 1.3, 2 RTTs com 1.2). Numa conexão móvel 4G típica de 80 ms de RTT, isso são 160 ms a 240 ms economizados por origem. Para a origem do LCP, esse costuma ser o hint de maior impacto absoluto.
<!-- Atributo crossorigin e obrigatorio para fontes e qualquer recurso CORS -->
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://cdn.exemplo.com">
A regra do crossorigin trava muita gente: se o recurso final será requisitado em modo CORS (fontes via @font-face, módulos ES, fetch() sem credentials), o preconnect também precisa do atributo, senão o browser abre uma segunda conexão e o hint é desperdiçado. Honestamente, eu mesmo já perdi uma tarde inteira de auditoria por causa de um crossorigin faltando. Para fontes self-hosted, leia nosso guia de otimização de fontes web com woff2 e font-display.
preload: para recursos críticos descobertos tarde
O preload instrui o browser a fazer fetch imediato de um recurso da página atual, com a prioridade indicada pelo atributo as. É a ferramenta certa quando o preload scanner do navegador não consegue descobrir o recurso sozinho. Normalmente: fontes referenciadas dentro de CSS, imagens hero usadas como background, ou módulos importados dinamicamente.
O atributo as é obrigatório. Sem ele, o browser faz duas requisições (uma especulativa, outra real). Os valores aceitos em 2026 incluem script, style, font, image, fetch, track, video, audio e document. A documentação canônica está nos docs MDN sobre rel="preload".
Cuidado com o efeito contrário: preload usa a prioridade High ou Highest, então cada preload rouba banda de outro recurso. Pré-carregar três imagens "para garantir" costuma atrasar o CSS crítico em 200 a 400 ms. A regra prática: no máximo dois preloads acima da dobra, e somente para recursos que afetam diretamente o LCP ou que precisam estar prontos antes do First Contentful Paint.
modulepreload: específico para módulos ES
Para aplicações que usam <script type="module">, o modulepreload é estritamente superior a preload as="script". A diferença: preload apenas baixa o arquivo, enquanto modulepreload também parseia, compila e resolve recursivamente as dependências declaradas em import. Para uma árvore de 50 módulos, isso converte 50 round-trips sequenciais em downloads paralelos.
Bundlers modernos como Vite 6 e Rollup 4 já geram automaticamente as tags modulepreload para todas as dependências estáticas do entry point. Se você usa um bundler antigo ou serve módulos sem bundling (estratégia "unbundled in dev"), gerar as tags manualmente é o que separa um SPA de 300 ms de um SPA de 1.2 s no first interaction.
prefetch: navegação futura e cache ocioso
Diferente dos outros quatro hints, o prefetch não é para a página atual. Ele é para a próxima. Baixa o recurso com prioridade Lowest, armazena no cache HTTP, e servirá tudo isso instantaneamente quando o usuário navegar para a página alvo. É a base de "next-page prefetching" usada por Next.js, Nuxt e SvelteKit em produção.
<!-- Pre-busca o HTML e o bundle JS da pagina de checkout -->
<link rel="prefetch" href="/checkout" as="document">
<link rel="prefetch" href="/assets/checkout-abc123.js" as="script">
O prefetch só executa quando a rede está ociosa, e respeita o cabeçalho Save-Data em conexões medidas. Em 2026, para navegação completa de página, o prefetch está sendo gradualmente substituído pela Speculation Rules API com prerendering e bfcache, que oferece prerender completo (renderização da página em background) em vez de só cache HTTP. Mas o prefetch continua relevante para sub-recursos individuais (imagens, fontes, dados JSON) e para browsers que ainda não suportam Speculation Rules.
Um anti-padrão comum: usar prefetch para recursos da página atual. Como a prioridade é mínima, o browser pode atrasar o fetch por segundos. Para recursos necessários agora, use preload.
fetchpriority e a Priority Hints API
O atributo fetchpriority (parte da Priority Hints API, Baseline 2024) permite ajustar a prioridade de qualquer fetch: em <img>, <script>, <link>, ou via fetch() com a opção priority. Os valores são "high", "low" e "auto" (padrão).
<!-- Imagem hero promovida diretamente, sem precisar de preload -->
<img src="/hero.avif" alt="..." fetchpriority="high" width="1200" height="600">
<!-- Imagem abaixo da dobra com prioridade reduzida -->
<img src="/banner.avif" alt="..." fetchpriority="low" loading="lazy">
<!-- Em JavaScript -->
fetch('/api/dados.json', { priority: 'high' });
Para a maioria dos casos de imagem LCP, <img fetchpriority="high"> tornou o <link rel="preload" as="image"> redundante, e bem mais simples de implementar. O Chrome relatou em sua documentação oficial da Priority Hints API ganhos médios de 9 a 14% no LCP em testes A/B reais. No último projeto em que apliquei isso (um e-commerce com hero responsivo), o p75 do LCP caiu de 2.6 s para 2.1 s só removendo dois preloads antigos e promovendo a <img>. Para entender como isso interage com a otimização de imagens, veja nosso guia completo de otimização de imagens com AVIF, WebP e fetchpriority.
Tabela comparativa dos resource hints
Hint
Fase
Custo
Quando usar
Limite recomendado
dns-prefetch
DNS apenas
~1 pacote UDP
Hosts secundários (analytics, ads)
Até 8 por página
preconnect
DNS + TCP + TLS
~50 KB no servidor
Origens críticas do LCP
Até 4 por página
preload
Fetch da página atual
Banda + prioridade Alta
Recursos descobertos tarde (fontes em CSS, hero background)
Até 2 acima da dobra
modulepreload
Fetch + parse + compile
Banda + CPU
Módulos ES e suas dependências
Toda a árvore do entry
prefetch
Fetch ocioso para próxima nav.
Banda em idle
Sub-recursos de páginas prováveis
Sem limite estrito
fetchpriority
Ajuste de prioridade
Zero
Promover/rebaixar fetches existentes
1 promoção High por página
Erros comuns e como evitá-los
Em mais de uma centena de auditorias de performance que conduzi, vejo os mesmos erros se repetirem:
Pré-carregar fontes sem crossorigin: faz o browser baixar a fonte duas vezes. Sempre adicione crossorigin em preload de as="font", mesmo para fontes same-origin.
Usar preload para "qualquer coisa importante": cada preload compete pela banda dos primeiros 14 KB do TCP slow start. Pré-carregar quatro imagens atrasa o CSS crítico.
Esquecer as= em preload: sem as, o browser faz uma requisição especulativa de baixa prioridade e depois a real. Pior do que simplesmente não usar.
Confundir prefetch com preload:prefetch pode demorar segundos para executar; nunca o use para recursos da página atual.
Aplicar resource hints em rotas dinâmicas: se a fonte do LCP muda por página, hints estáticos no <head> global desperdiçam download. Use injeção via framework (Next.js <Head>, Remix links()) por rota.
Não auditar o ganho real: compare o LCP antes e depois via WebPageTest com run count igual ou maior que 5. Sem medição, todo hint vira ruído.
Como medir o impacto no LCP e TTFB
Toda mudança de resource hint precisa ser validada com dados, não com intuição. O fluxo que uso em cada auditoria:
Baseline no DevTools: abra o painel Network, marque "Disable cache", recarregue com throttling "Fast 4G". Anote o tempo do recurso LCP e a coluna "Priority".
Lighthouse 12 ou superior, Performance Insights: rode em modo "Navigation", aba "Performance Insights". A seção "Render-blocking requests" e "LCP request discovery" sinaliza onde um hint ajudaria.
WebPageTest com 9 runs: compare percentil mediano entre versão com e sem o hint. Variação intra-run em mobile passa de mais ou menos 150 ms; sem múltiplas amostras, o ganho some no ruído.
Field data via CrUX: após o deploy, observe os percentis p75 de LCP em Chrome User Experience Report. Hints bem aplicados movem o p75, não só o p50.
preload baixa recursos da página atual com prioridade alta (executa imediatamente). prefetch baixa recursos da próxima navegação com prioridade mínima, em momentos de ociosidade da rede. Usar um pelo outro causa atraso ou desperdício de banda.
Quantos preconnect posso usar em uma página?
Limite a 3 ou 4 origens críticas. Cada preconnect consome memória no servidor remoto e banda no TCP slow start. Em testes do Chrome, ir além de 4 conexões antecipadas costuma piorar o LCP em vez de melhorá-lo.
Preciso usar preload se já estou usando fetchpriority?
Para a imagem LCP no HTML, <img fetchpriority="high"> normalmente substitui o <link rel="preload"> e é mais simples. Mas o preload ainda é necessário para recursos invisíveis ao preload scanner: fontes em CSS, módulos importados dinamicamente, imagens em background-image.
O atributo crossorigin é sempre obrigatório?
Não. É obrigatório quando o recurso final será requisitado em modo CORS: sempre para fontes (as="font"), módulos ES, e fetch() sem credentials. Para scripts comuns e imagens same-origin, omita.
Resource hints funcionam em Safari e Firefox?
Sim, todos os cinco hints discutidos têm suporte universal em Chromium, Firefox 115 ou superior e Safari 17.2 ou superior. O atributo fetchpriority chegou ao Safari 17.2 e Firefox 119, então é Baseline desde o início de 2024.
Devo usar Speculation Rules em vez de prefetch?
Para navegação completa entre páginas, sim. A Speculation Rules API faz prerender (renderiza a página em background) e oferece navegação instantânea, enquanto o prefetch só preenche o cache HTTP. Mas o prefetch continua útil para sub-recursos individuais e em browsers sem suporte a Speculation Rules.
TTFB abaixo de 200 ms exige atacar rede, servidor e cache em três frentes. Guia prático com CDN, HTTP/3, Early Hints, streaming SSR e exemplos de código.
Como implementar navegação instantânea com a Speculation Rules API, prerendering e bfcache. Guia prático com exemplos de código, resultados reais e a estratégia em camadas para otimizar os Core Web Vitals do seu site.