Um Guia de Core Web Vitals para Priorização de Recursos
Não deixe o navegador adivinhar. Force-o a carregar o que importa quando importa!

Guia de Core Web Vitals para Priorização de Recursos
O mecanismo de priorização padrão do navegador opera com heurísticas (suposições imperfeitas baseadas em tipos de arquivo e localização no documento). Os recursos são enfileirados com base em quando são descobertos pelo preload scanner ou pelo DOM parser.

Isso pode se tornar um problema quando você considera que a largura de banda da rede e a CPU não são recursos ilimitados. Por exemplo: cada byte transferido para um script de rastreamento de baixa prioridade, enquanto é baixado ao mesmo tempo, compete diretamente com os bytes necessários para o seu Largest Contentful Paint (LCP).
Isso não é culpa do navegador: no HTML do nosso exemplo, o navegador não tinha como saber que havia priorizado os recursos errados, o que atrasou a renderização crítica.
Você é quem sabe o que é importante e controla essa programação através de dois mecanismos: Priorização (amplificando sinais críticos) e Despriorização (agendando recursos não críticos para quando forem menos intrusivos).
Table of Contents!
Limitações das Heurísticas do Navegador
Os navegadores atribuem prioridade com base em uma pontuação de "prioridade calculada". Essa pontuação deriva do tipo de recurso (CSS, Script, Imagem) e sua posição no HTML/DOM. Embora geralmente eficaz para documentos simples, esse sistema falha quando os recursos não são reconhecidos cedo (pelo preload scanner) ou quando os recursos errados são acionados para um download antecipado.
A Limitação do Preload Scanner
Para acelerar a descoberta, os navegadores empregam um "preload scanner", um parser leve que avança à frente do parser HTML principal para encontrar URLs de recursos. Esse scanner tem limitações (que o tornam rápido e eficaz): ele analisa apenas HTML. Não consegue ver dentro de arquivos CSS, não executa JavaScript e não renderiza (portanto, não consegue 'ver se os recursos estão visíveis na viewport').
Como consequência, qualquer recurso referenciado em uma folha de estilos (como uma imagem de fundo ou uma web font), injetado por um script ou com lazy loading, é ignorado ou nem mesmo visto até que o parser principal baixe e processe toda a página web. Isso cria um "atraso de descoberta", onde o navegador efetivamente desconhece que recursos críticos existem.
Contenção de Recursos
Quando o navegador descobre recursos, ele frequentemente tenta baixá-los simultaneamente com outras requisições pendentes. Se uma imagem LCP importante compete com um script de prioridade média ou imagens sem importância (como ícones de redes sociais no rodapé), eles dividem a largura de banda disponível. Essa contenção estende o tempo de carregamento de ambos, empurrando a métrica LCP para a zona "Needs Improvement".
Estratégias de Priorização Manual
Para construir um caminho de renderização rápido, você deve intervir manualmente. O objetivo é maximizar a largura de banda para o LCP e minimizá-la para todo o resto.
1. Corrija a Descoberta com Preloading
Você deve expor manualmente recursos ocultos ao preload scanner. Ao mover recursos críticos para o HTML <head> usando rel="preload", você força o navegador a reconhecê-los imediatamente, eliminando o atraso de descoberta.
A Implementação:
<!-- Exponha a fonte ao scanner imediatamente --> <link rel="preload" as="font" type="font/woff2" href="/fonts/inter-bold.woff2" crossorigin> <!-- Exponha a imagem LCP de fundo imediatamente --> <link rel="preload" as="image" href="/images/hero-banner.jpg" fetchpriority="high">
2. Substitua as Heurísticas do LCP
Os navegadores frequentemente atribuem prioridade "Low" ou "Medium" a imagens porque não conhecem as dimensões finais do layout durante a busca inicial. O navegador não consegue determinar se uma imagem é o LCP até que a árvore de renderização seja construída, o que é tarde demais.
A Implementação:
Force o status de prioridade "High" no elemento LCP usando fetchpriority="high". Isso ignora as heurísticas internas e coloca a imagem na frente da fila de download.
<!-- Force a busca imediata com alta prioridade --> <img src="hero.jpg" alt="Hero Product" fetchpriority="high">
3. Despriorize Imagens Sem Importância
Liberar largura de banda é frequentemente mais eficaz do que aumentar a prioridade. Você deve explicitamente atrasar recursos não essenciais para limpar o canal de rede para recursos críticos.
A Implementação:
- Below-the-fold: Use loading="lazy" para adiar o download até que o usuário role a página.
- Above-the-fold Secundário: Use fetchpriority="low" para slides de carrossel ou visuais secundários que renderizam inicialmente, mas são menos importantes que o LCP.
- Above the fold e visualmente sem importância: Contorne o preload scanner usando loading="lazy" e atribua uma largura de banda baixa. Útil para aquelas pequenas imagens como bandeiras ou ícones que nunca chamam a atenção durante a primeira renderização, mas podem acionar muitas requisições de largura de banda antecipadas.
<!-- Imagem LCP: Prioridade Máxima --> <img src="slide-1.jpg" fetchpriority="high"> <!-- Imagem Secundária do Carrossel: Busca imediata, baixo uso de largura de banda --> <img src="slide-2.jpg" fetchpriority="low"> <!-- Bandeiras de tradução: enquanto na viewport, esconda-as do preload scanner --> <img src="dutch-flag.jpg" loading="lazy" fetchpriority="low"> <!-- Imagem Fora da Tela: Busca adiada --> <img src="footer-promo.jpg" loading="lazy">
4. Controle a Execução de Scripts
JavaScript bloqueia o DOM parser. Se você usar tags <script> padrão, o navegador interrompe a análise do HTML para baixar e executar o arquivo.
A Implementação:
- defer: Use para lógica da aplicação. Faz o download em paralelo (baixa prioridade) e executa somente após o HTML ser completamente analisado, preservando a ordem de dependências.
- async: Use para scripts independentes de terceiros (como analytics). Faz o download em paralelo e executa imediatamente ao ser concluído, desconsiderando a ordem.
- Inject: Contorna o preload scanner para que não compita com a largura de banda inicial. Scripts injetados são tratados como async.
- Schedule + Inject: Injete scripts em um momento posterior, por exemplo quando o evento load for disparado.
<!-- Lógica da Aplicação: Não bloqueante, preserva a ordem de execução -->
<script src="app.js" defer></script>
<!-- Consentimento de Terceiros: Não bloqueante, execução independente -->
<script src="consent.js" async></script>
<script>
/* Exemplo de injeção de analytics */
const script = document.createElement('script');
script.src = 'analytics.js';
script.async = true;
document.head.appendChild(script);
/* Exemplo de injeção + agendamento para chat */
window.addEventListener('load', () => {
const chatScript = document.createElement('script');
chatScript.src = 'chat-widget.js';
document.head.appendChild(chatScript);
});
</script>5. Desbloqueie a Renderização de CSS
CSS é bloqueante de renderização por design: o navegador não sabe como a página se parece sem CSS. Então ele baixa e analisa as folhas de estilo primeiro.
Estratégias de Otimização:
- Evite @import: Cria cadeias de dependência sequenciais que devastam a performance.
- Otimize o Tamanho do Bundle: Evite arquivos CSS menores que 3kB (overhead) e maiores que 20kB (bloqueantes). Idealmente, mire em arquivos de ~15kB.
- Carregamento Assíncrono: Carregue estilos fora da tela de forma assíncrona para desbloquear o caminho crítico.
- Tradeoff do CSS Crítico: Embora embutir CSS Crítico melhore a primeira visualização da página, isso ignora o cache do navegador, o que pode atrasar visualizações subsequentes.
A Implementação:
Elimine @import completamente. Use tags <link> para carregamento paralelo. Para CSS não crítico (como estilos de impressão), use o atributo media para desbloquear a thread principal.
<!-- CSS Crítico: Bloqueia a renderização (Correto) --> <link rel="stylesheet" href="main.css"> <!-- CSS de Impressão: Não bloqueante até que o evento de impressão ocorra --> <link rel="stylesheet" href="print.css" media="print"> <!-- Padrão Assíncrono: Carrega com baixa prioridade, aplica no load --> <link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">
6. Estabilize a Renderização de Fontes
Fontes são recursos bloqueantes pesados. Uma priorização eficaz requer limites rigorosos sobre o que é baixado e controle sobre como é renderizado.
Estratégias de Otimização:
- Limites Rigorosos de Preload: Faça preload apenas dos 1-2 arquivos de fonte mais importantes (geralmente texto do LCP). Fazer preload de 5+ fontes congestiona a largura de banda.
- Reduza o payload: Use Variable Fonts (um arquivo para todos os pesos) e Subsetting (remova caracteres não utilizados) para minimizar o tamanho do arquivo.
- Estratégia de Renderização:
- Use
swappara renderização rápida (evita FOIT/texto invisível). - Use
optionalpara prevenir CLS (evita layout shifts em redes lentas).
- Use
A Implementação:
<!-- Faça preload APENAS do subconjunto crítico (ex: Header + Body) -->
<link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<style>
@font-face {
font-family: 'Inter Variable';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
/* Escolha com base nos requisitos de estabilidade: */
font-display: optional; /* Sem layout shift, mas a fonte pode permanecer como fallback */
/* font-display: swap; Visibilidade de texto mais rápida, mas com risco de layout shift */
}
</style>
Ask AI why your INP spiked.
CoreDash is the only RUM tool with MCP support. Connect it to your AI agent and query your Core Web Vitals data in natural language. No more clicking through dashboards.
See How It Works
