JavaScript no Head vs Footer: Como Isso Afeta os Core Web Vitals
Por que o defer no head é a melhor prática moderna, e quando colocá-lo no footer ainda faz sentido

A resposta curta: defer no head
Última revisão por Arjen Karel em Março de 2026
A recomendação clássica era colocar o JavaScript no rodapé (footer). Esse conselho está desatualizado. Com o suporte a async e defer em todos os navegadores, o melhor lugar para a maioria dos scripts é no <head> com um atributo defer.
O motivo se resume ao preload scanner (analisador de pré-carregamento): o seu navegador descobre os scripts no head imediatamente e começa a baixá-los em paralelo com a análise (parsing) do HTML. Os scripts no footer são descobertos mais tarde, o que significa um início de download mais tardio. O resultado é o mesmo comportamento não bloqueante (non-blocking), mas com uma descoberta de recursos mais rápida.
De acordo com o Web Almanac de 2025, 85% das páginas ainda falham na auditoria de recursos de bloqueio de renderização (render-blocking). Este é um número enorme. Enquanto isso, o Total Blocking Time (Tempo Total de Bloqueio) em dispositivos móveis aumentou 58% ano a ano, atingindo uma mediana de 1.916 ms. O JavaScript está ficando mais pesado, não mais leve. Acertar a localização do seu script é uma das coisas mais fáceis que você pode fazer para melhorar o seu First Contentful Paint e o Largest Contentful Paint.
Como o preload scanner funciona
O preload scanner é um segundo analisador HTML que funciona à frente do analisador principal. Ele examina rapidamente o HTML bruto e começa a buscar recursos críticos (imagens, CSS, JavaScript) antes que o analisador principal chegue até eles. O preload scanner busca os recursos mais ou menos na ordem em que os descobre.
É aqui que o local do script importa. Um script no <head> é descoberto quase imediatamente. Um script no final do <body> é descoberto mais tarde, especialmente em documentos HTML grandes. Esse atraso pode lhe custar centenas de milissegundos em uma conexão móvel.
Scripts injetados dinamicamente (criados via JavaScript) são totalmente invisíveis para o preload scanner. O scanner descobre apenas os recursos que existem na marcação (markup) HTML retornada pelo servidor. É por isso que adiar (defer) o JavaScript por meio de atributos HTML é quase sempre melhor do que injetar scripts com código.
JavaScript no head
Colocar o JavaScript no <head> da página proporciona a descoberta mais precoce possível pelo preload scanner.
Vantagens
- Descoberta antecipada: O preload scanner encontra os scripts do head antes de qualquer conteúdo do body. O download começa o mais cedo possível.
- Execução mais cedo: Scripts no head (com
defer) executam antes dos scripts descobertos mais tarde no documento. Para uma comparação detalhada, veja JavaScript defer vs async e os Core Web Vitals. - Separação de código: Manter as referências de script no
<head>as separa da marcação de conteúdo, tornando o HTML mais fácil de manter.
Desvantagens
- Bloqueio de renderização (sem defer ou async): Um
<script>simples no head bloqueia a análise do HTML até que o script seja baixado e executado. Isso acaba com o seu First Contentful Paint. Sempre usedeferouasyncem scripts externos no head para evitar isso. - Competição por largura de banda: Scripts do head de alta prioridade competem por largura de banda (bandwidth) com seu CSS, fontes e imagem LCP. Em conexões mais lentas, isso pode empurrar seu Largest Contentful Paint para além do limite de 2,5 segundos.
Quando usar a colocação no head
Use o <head> para scripts que são críticos para a experiência da página: seu menu, aviso de cookies, slider ou qualquer script que afete o que o visitante vê acima da dobra (above the fold). Adicione defer (ou async se a ordem de execução não importar) para evitar o bloqueio de renderização. Bibliotecas de detecção de recursos (feature detection) também pertencem ao head, já que precisam ser executadas antes que o body seja analisado.
JavaScript no footer
Colocar o JavaScript logo antes da tag de fechamento </body> foi o conselho de performance padrão por anos. A ideia: deixar o HTML renderizar primeiro, baixar os scripts depois.
Vantagens
- Não bloqueante por padrão: Scripts de footer não bloqueiam a renderização inicial porque o HTML acima deles já foi analisado.
- Menor competição por largura de banda: No momento em que o navegador chega aos scripts do footer, seu CSS, fontes e imagem LCP já começaram a ser baixados.
Desvantagens
- Descoberta tardia: O preload scanner encontra scripts no footer mais tarde do que scripts no head. Em uma página grande, isso significa um início de download e uma execução mais tardios.
- Padrão obsoleto:
<script defer>no<head>atinge o mesmo comportamento não bloqueante com descoberta mais cedo. A colocação no footer era a solução alternativa (workaround) antes dodeferter suporte universal nos navegadores. Essa era acabou.
Quando a colocação no footer ainda faz sentido
A colocação no footer pode fazer sentido para scripts que você realmente não quer que compitam por largura de banda durante o carregamento inicial da página: analytics, ferramentas de teste A/B ou widgets sociais. Mas mesmo para estes, o defer no head costuma ser a melhor escolha devido à descoberta mais precoce pelo preload scanner.
Atributos de script modernos
Além do async e do defer, existem mais dois atributos que valem a pena conhecer:
type="module": Scripts de módulo (module) são adiados (deferred) por padrão. Você não precisa adicionar defer a um script module porque ele já se comporta dessa maneira. Adicionar async a um script module substitui o comportamento padrão de adiamento e faz com que ele seja executado assim que terminar de baixar.
fetchpriority: Por padrão, scripts async e defer recebem prioridade de rede Baixa (Low). Adicionar fetchpriority="high" a um script async lhe dá um download não bloqueante com prioridade Alta (High). Essa é a combinação ideal para scripts que são cruciais para a user experience, mas que não devem bloquear a renderização. Para o cenário completo, veja o guia para priorização de recursos e os níveis de prioridade do JavaScript.
Uma estratégia prática para a localização de scripts
Nem todos os scripts merecem o mesmo tratamento. Eu uso uma abordagem de quatro níveis:
- Scripts críticos para a renderização: Scripts que afetam o layout visível da página (menu, slider, interface acima da dobra). Coloque no
<head>sem odeferse eles precisarem ser executados antes do primeiro paint. Mantenha-os o menor possível, porque eles bloqueiam a renderização e prejudicarão os seus Core Web Vitals. - Scripts importantes: Scripts cruciais para conversão ou interação (formulários, navegação, consentimento de cookies). Coloque no
<head>comdeferouasync. - Scripts normais: Scripts que não afetam a primeira renderização da página (carrosséis, modais, abas). Coloque no
<head>comdefer. - Scripts bons de se ter (nice-to-have): Scripts dos quais você poderia abrir mão se fosse absolutamente necessário (analytics, widgets de chat, compartilhamento social). Carregue-os depois que a página terminar de renderizar, usando o evento
loadourequestIdleCallback. Veja 16 métodos para adiar o JavaScript em busca de técnicas. Se você possui muito JavaScript não utilizado nessa categoria, veja como reduzir o JavaScript não utilizado.
Os eventos DOMContentLoaded e load permitem que você controle o momento de execução (timing), independentemente de onde o script está localizado no HTML. Isso é útil para garantir que seu código seja executado no momento certo.
Exemplos de código
Exemplo 1: JavaScript no head (bloqueio de renderização)
<!DOCTYPE html>
<html>
<head>
<title>Exemplo de JavaScript no Head</title>
<script>
function showMessage() {
alert("Olá do JavaScript no head!");
}
</script>
<!-- Este script bloqueia a renderização -->
<script src="script.js"></script>
</head>
<body>
<button onclick="showMessage()">Clique Aqui</button>
</body>
</html>
Neste exemplo, o script.js no <head> bloqueia a renderização. O navegador não exibirá o botão até que o script tenha sido baixado e executado. Adicione o defer à tag script para consertar isso.
Exemplo 2: JavaScript no footer
<!DOCTYPE html>
<html>
<head>
<title>Exemplo de JavaScript no Footer</title>
</head>
<body>
<button onclick="showMessage()">Clique Aqui</button>
<!-- Script no final do body -->
<script src="script.js"></script>
<script>
function showMessage() {
alert("Olá do JavaScript no footer!");
}
</script>
</body>
</html>
Aqui, o script.js carrega depois do conteúdo HTML, então ele não bloqueia a renderização. Mas o preload scanner o descobre mais tarde do que descobriria no head. Usar <script defer src="script.js"></script> no <head> oferece o mesmo comportamento não bloqueante com uma descoberta de download antecipada.
Exemplo 3: Usando event listeners
<!DOCTYPE html>
<html>
<head>
<title>Exemplo de Event Listener</title>
<script>
window.addEventListener('load', function() {
console.log("A página está totalmente carregada.");
});
</script>
</head>
<body>
<!-- Conteúdo da página -->
</body>
</html>
O event listener de load assegura que o código dentro do callback seja executado somente depois que a página estiver totalmente carregada, não importando onde o script seja colocado. Isso é proveitoso para inicializações que não são críticas e que devam aguardar até que tudo o mais esteja preparado.
Verifique as suas mudanças
Depois de migrar os scripts do footer (rodapé) para o defer no <head>, certifique-se do impacto usando Real User Monitoring. O seu FCP e o LCP devem melhorar os dois em uníssono. Englobando os sites monitorados pela CoreDash, as origens (origins) que adotam o defer em grande parte dos seus scripts revelam uma mediana correspondente a um FCP com velocidade 18% maior no que diz respeito as origens dependentes e baseadas na alocação no rodapé.
The RUM tool I built for my own clients.
CoreDash is what I use to audit enterprise platforms. Under 1KB tracking script, EU hosted, no consent banner. AI with MCP support built in. The same tool, available to everyone.
Create Free Account
