Imagens, scripts e fontes: como definir o que realmente precisa ser carregado primeiro

Diagnostique as causas de saltos visuais durante o carregamento de tipografias e implemente estratégias de pré-carregamento com a propriedade font-display.

OTIMIZAÇÃO DE CÓDIGO

10/10/20267 min read

A prioridade de um recurso deve refletir a função que ele exerce na renderização e na interação inicial. Isso não significa baixar tudo antes de tudo. Antecipar imagens, scripts e fontes sem critério pode ocupar a banda, disputar conexões e atrasar o recurso que realmente está no caminho crítico.

A pergunta correta é: qual recurso precisa estar disponível para o usuário perceber o conteúdo principal ou realizar a primeira ação importante? Em uma notícia, pode ser a imagem principal. Em um checkout, pode ser o JavaScript que habilita a seleção de entrega. Em um artigo, uma fonte personalizada pode ser secundária se o texto já aparece com uma fonte de sistema aceitável.

Como o navegador descobre e ordena recursos

O navegador recebe o HTML e começa a analisá-lo. O parser e o preload scanner encontram referências como src, srcset, href e script src. Depois, heurísticas atribuem uma prioridade de busca considerando o tipo do recurso, sua posição no documento e atributos como async, defer e fetchpriority. Recursos com a mesma prioridade tendem a ser solicitados na ordem em que foram descobertos, segundo a documentação sobre Fetch Priority .

Esses conceitos não são equivalentes:

•Descoberta é o momento em que o navegador fica sabendo que um recurso existe. Uma imagem no HTML é mais fácil de descobrir do que uma imagem de fundo definida em CSS ou criada depois por JavaScript.

•Prioridade de rede é a preferência relativa entre recursos já conhecidos. fetchpriority="high" é uma indicação, não uma ordem absoluta.

•Dependência é a relação que obriga uma etapa a esperar outra. Um script pode depender de módulos, dados e DOM; uma fonte em uma folha externa depende da descoberta e do processamento dessa folha.

•Carregamento preguiçoso adia a busca até que o recurso esteja próximo de ser necessário. É útil para conteúdo abaixo da dobra, mas pode ser inadequado para o elemento visual principal.

preload atua principalmente na descoberta: inicia cedo a busca de um recurso que seria descoberto tarde. prefetch é especulativo e de baixa prioridade: prepara um recurso para uma navegação futura que pode nem ocorrer. fetchpriority influencia a prioridade relativa de uma busca conhecida. A documentação de dicas de recursos do web.dev recomenda limitar preload a recursos críticos descobertos tarde .

Imagens, scripts e fontes no caminho crítico

Imagem principal e conteúdo visível

Comece identificando o que o usuário vê primeiro. Se a imagem principal for candidata a LCP (Largest Contentful Paint), ela deve ser descobrível no HTML sempre que possível. O guia de otimização de LCP recomenda observar o atraso até o início da busca, a duração do download e o atraso até a renderização .

Uma imagem acima da dobra não é automaticamente a mais importante. Num carrossel, apenas o primeiro slide pode ser necessário para a primeira pintura. Miniaturas e slides seguintes podem ter prioridade menor ou carregamento posterior. loading="lazy" não deve ser aplicado cegamente: se o recurso for o LCP, o atraso na descoberta pode piorar a hipótese que se pretendia otimizar.

Quando a imagem crítica está no HTML, o navegador pode encontrá-la sem preload. Quando ela é um background-image ou só aparece depois de JavaScript, preload pode resolver a descoberta tardia, desde que a URL e o tipo sejam conhecidos e o recurso seja realmente usado.

Scripts necessários à interação

O JavaScript inicial deve ser separado pela função, não apenas pelo tamanho. Um script que abre o menu, valida o formulário visível ou permite escolher uma variante de produto pertence ao caminho da primeira interação. Analytics, chat ou mapa de uma área secundária geralmente não têm a mesma urgência.

Um script clássico sem async, defer ou type="module" é buscado e executado antes de o parser continuar. async permite buscar em paralelo, mas executa assim que termina, sem garantir a ordem entre scripts. É apropriado quando os scripts são independentes. defer também permite a busca sem bloquear o parser e executa depois da análise do documento, preservando a ordem dos scripts adiados. Essas diferenças estão na referência do elemento script do MDN .

Isso não transforma todo script em candidato a prioridade alta. Mesmo um script assíncrono pode disputar banda e CPU com a imagem principal. A decisão deve considerar o momento em que a interação pode ocorrer e o que acontece se o script ainda não estiver disponível.

Fontes críticas e alternativas

Fontes web são descobertas a partir de @font-face, normalmente depois que a folha de estilos é baixada e processada. O navegador evita baixar uma fonte que o layout atual não precisa. A documentação de fontes web explica que preload pode antecipar a descoberta, mas deixa de esperar a confirmação de uso .

A fonte só deve ser antecipada quando participa de conteúdo inicial importante e a família, o peso e a variante forem conhecidos. Uma fonte de ícones de um componente que talvez nem apareça não deve competir com o conteúdo principal. font-display também altera a experiência: uma alternativa do sistema pode mostrar o texto antes, enquanto a fonte personalizada chega depois, com possível troca visual.

Matriz de decisão

Recurso

Função na página

Quando pode ser prioritário

Dependências

Risco de antecipar

Como verificar

Imagem hero

Conteúdo visual principal

Quando é o destaque visível ou o LCP

HTML, CSS e dimensões

Banda ocupada por imagem não vista

LCP, waterfall e Initiator

Miniaturas ou slides seguintes

Conteúdo secundário

Quando a interação inicial exige o próximo item

Carrossel e dados

Disputa com hero e scripts

Waterfall e troca de slide

Script de menu ou formulário

Interação inicial

Quando o controle visível depende dele

DOM, módulos e APIs

CPU ocupada ou ordem incorreta

Console e teste funcional

Analytics, chat ou publicidade

Terceiro ou função não essencial

Só se houver requisito imediato comprovado

Origem externa e consentimento

Conexões e execução concorrentes

Filtro de terceiros e Console

Fonte do título principal

Aparência do conteúdo inicial

Quando a tipografia é essencial à leitura

CSS, @font-face e variante

Download inútil ou troca visual

Waterfall e fonte aplicada

Fonte de componente abaixo da dobra

Aparência secundária

Quando o componente está prestes a ser usado

CSS e componente

Antecipação sem uso

Rolagem e waterfall

Dois exemplos hipotéticos

Página cujo destaque é uma imagem. Uma página de receita exibe foto grande, título e texto no HTML inicial. A foto é candidata a LCP; o mapa de restaurantes aparece mais abaixo. A hipótese é manter a foto no HTML, garantir dimensões conhecidas e avaliar fetchpriority="high" apenas se a observação indicar que a heurística não a trata como suficientemente importante. O mapa não deve receber preload por estar na mesma página. Se a foto estiver em CSS, pode haver uma hipótese de preload, confirmada no waterfall e removida se o recurso não for usado.

Página cuja primeira interação depende de script. Uma página de produto mostra um seletor de tamanho que precisa de JavaScript para atualizar preço e disponibilidade. O script do componente pode fazer parte do caminho crítico, enquanto chat e avaliações podem aguardar. A hipótese é garantir a cadeia necessária — módulo, dependências, dados e DOM — escolhendo defer, async ou carregamento sob demanda conforme a ordem exigida. O resultado funcional deve ser testado, sem atribuir ganho medido que não foi observado.

Riscos de antecipar recursos

preload é adequado para recursos críticos e descobertos tarde, não para uma lista de arquivos “importantes”. Se o recurso não for usado, a banda foi desperdiçada; se a declaração não coincidir com a requisição final, pode haver busca duplicada. Fontes exigem atenção a CORS: a documentação alerta que um preload sem o crossorigin correto pode resultar em download duplicado .

prefetch não deve consertar o caminho crítico da página atual. Ele prepara uma possível navegação futura e pode consumir recursos mais úteis agora. fetchpriority="high" deve ser reservado a poucos casos defendidos por uma hipótese. Ele não corrige dependências ausentes, URLs descobertas tarde por lógica de aplicação ou arquivos excessivamente grandes.

async e defer alteram a ordem e o instante de execução. O comportamento deve ser compatível com as dependências reais. O carregamento preguiçoso deve ficar restrito a recursos não essenciais, desde que a experiência continue correta.

Como verificar sem adivinhar

No Chrome DevTools, abra Network, recarregue a página e filtre por Img, JS e Font. A referência do painel Network mostra como exibir Priority, Initiator e Waterfall . O waterfall revela quando a busca começou e quanto tempo ficou esperando; Initiator indica se ela veio do parser, de um script ou de outra dependência.

Para a hipótese visual, identifique o elemento LCP em uma execução de laboratório e associe-o à URL no waterfall. Para a hipótese de interação, observe se o controle funciona, examine erros no Console e verifique a cadeia de módulos e dados. Dados de laboratório descrevem uma execução com dispositivo, rede e configuração definidos; dados de campo representam usuários reais e podem mostrar outro caminho, região e cache. Nenhum deles, isoladamente, prova uma causa universal.

Faça mudanças em staging, uma variável por vez quando possível, com cópia de segurança e plano de reversão. Repita em dispositivos e redes variados e confira aparência, acessibilidade e funcionamento antes da publicação.

Fluxo de decisão

1.Identifique o conteúdo visível dominante e a primeira interação que precisa funcionar.

2.Liste os recursos necessários e desenhe as dependências.

3.Verifique se cada recurso já é descoberto cedo pelo HTML e pelo preload scanner.

4.Se for descoberto tarde e for realmente crítico, considere preload; se já for conhecido, avalie primeiro prioridade e tamanho.

5.Adie ou carregue preguiçosamente o que está fora do caminho inicial.

6.Meça waterfall, LCP quando aplicável, Console e comportamento funcional.

7.Compare condições de laboratório e campo, teste em staging e só então publique.

A melhor arquitetura não é a que faz mais recursos começarem primeiro. É a que permite ao navegador descobrir e baixar primeiro aquilo que o usuário precisa perceber ou usar, preservando banda e CPU para o restante da página.

Referências

[1] Optimize resource loading with the Fetch Priority API

[2] Optimize Largest Contentful Paint

[3] <script>: The Script element

[4] Optimize web fonts

[5] Network features reference | Chrome DevTools

[6] Resource hints