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 o posicionamento no footer ainda faz sentido

A resposta curta: defer no head
Última revisão por Arjen Karel em março de 2026
O conselho clássico era colocar o JavaScript no 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.
A razão se resume ao preload scanner: seu navegador descobre os scripts no head imediatamente e começa a baixá-los em paralelo com o processamento do HTML. Scripts no footer são descobertos mais tarde, o que significa um início de download mais tardio. O resultado é o mesmo comportamento de não bloqueio, 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. Esse é um número enorme. Enquanto isso, o Total Blocking Time no mobile aumentou 58% ano a ano para uma mediana de 1.916 ms. O JavaScript está ficando mais pesado, não mais leve. Acertar o posicionamento do seu script é uma das coisas mais fáceis que você pode fazer para melhorar o seu First Contentful Paint e Largest Contentful Paint.
Como o preload scanner funciona
O preload scanner é um segundo analisador (parser) de HTML que é executado à frente do analisador principal. Ele examina rapidamente o HTML bruto e começa a buscar os recursos críticos (imagens, CSS, JavaScript) antes que o analisador principal chegue a eles. O preload scanner busca os recursos mais ou menos na ordem em que os descobre.
É aqui que o posicionamento do script importa. Um script no <head> é descoberto quase imediatamente. Um script na parte inferior do <body> é descoberto mais tarde, especialmente em documentos HTML grandes. Esse atraso pode custar centenas de milissegundos em uma conexão mobile.
Scripts injetados dinamicamente (criados via JavaScript) são totalmente invisíveis para o preload scanner. O scanner só descobre recursos que existem na marcação HTML retornada pelo servidor. É por isso que adiar 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 cedo possível pelo preload scanner.
Vantagens
- Descoberta antecipada: O preload scanner encontra os scripts no 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) são executados antes dos scripts descobertos mais tarde no documento. Para uma comparação detalhada, veja defer vs async JavaScript 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, facilitando a manutenção do HTML.
Desvantagens
- Bloqueio de renderização (sem defer ou async): Um simples
<script>no head bloqueia o processamento 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 de alta prioridade no head competem por largura de banda com o seu CSS, fontes e a imagem de LCP. Em conexões mais lentas, isso pode empurrar o seu Largest Contentful Paint para além do limite de 2,5 segundos.
Quando usar o posicionamento no head
Use o <head> para scripts que são essenciais para a experiência na 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 também pertencem ao head, já que precisam ser executadas antes que o body seja processado.
JavaScript no footer
Colocar o JavaScript logo antes da tag de fechamento </body> foi o conselho de desempenho padrão durante anos. A ideia: deixar o HTML ser renderizado primeiro, baixar os scripts depois.
Vantagens
- Não bloqueio por padrão: Scripts no footer não bloqueiam a renderização inicial porque o HTML acima deles já foi processado.
- Menor competição por largura de banda: No momento em que o navegador chega aos scripts no footer, seu CSS, fontes e imagem de 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 mais tardio e uma execução mais tardia.
- Padrão obsoleto:
<script defer>no<head>atinge o mesmo comportamento de não bloqueio com uma descoberta mais precoce. O posicionamento no footer era a solução alternativa antes de odeferter suporte universal nos navegadores. Essa era acabou.
Quando o posicionamento no footer ainda faz sentido
O posicionamento no footer pode fazer sentido para scripts com os quais você realmente não quer competir por largura de banda durante o carregamento inicial da página: analytics, ferramentas de teste A/B ou widgets sociais. Mas mesmo para esses, o defer no head geralmente é a melhor escolha devido à descoberta mais antecipada pelo preload scanner.
Atributos modernos de script
Além do async e defer, há mais dois atributos que vale a pena conhecer:
type="module": Scripts de módulo são adiados por padrão. Você não precisa adicionar defer a um script de módulo porque ele já se comporta dessa maneira. Adicionar async a um script de módulo substitui o comportamento de adiamento padrão e faz com que ele seja executado assim que o download terminar.
fetchpriority: Por padrão, os scripts async e defer obtêm prioridade de rede Baixa (Low). Adicionar fetchpriority="high" a um script assíncrono fornece um download sem bloqueio com prioridade Alta (High). Essa é a combinação ideal para scripts que são essenciais para a user experience, mas não devem bloquear a renderização. Para uma visão completa, veja o guia de priorização de recursos e os níveis de prioridade do JavaScript.
Uma estratégia prática de posicionamento de scripts
Nem todos os scripts merecem o mesmo tratamento. Eu uso uma abordagem de quatro níveis:
- Scripts críticos para renderização: Scripts que afetam o layout visível da página (menu, slider, UI acima da dobra). Coloque no
<head>semdeferse eles tiverem que ser executados antes da primeira renderização. Mantenha-os o menor possível, pois eles bloqueiam a renderização e prejudicarão 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 interessantes de se ter: Scripts sem os quais você poderia viver se fosse absolutamente necessário (analytics, widgets de chat, compartilhamento social). Carregue-os depois que a página terminar a renderização, usando o evento
loadourequestIdleCallback. Veja 16 métodos para adiar o JavaScript para obter técnicas. Se você tiver 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 tempo de execução independentemente de onde o script está colocado 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 em Mim</button>
</body>
</html>
Neste exemplo, 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 defer à tag de script para corrigir isso.
Exemplo 2: JavaScript no footer
<!DOCTYPE html>
<html>
<head>
<title>Exemplo de JavaScript no Footer</title>
</head>
<body>
<button onclick="showMessage()">Clique em Mim</button>
<!-- Script no final do body -->
<script src="script.js"></script>
<script>
function showMessage() {
alert("Olá do JavaScript no footer!");
}
</script>
</body>
</html>
Aqui, script.js é carregado após o conteúdo HTML, então ele não bloqueia a renderização. Mas o preload scanner o descobre mais tarde do que faria no head. Usar <script defer src="script.js"></script> no <head> lhe dá o mesmo comportamento sem bloqueio com uma descoberta de download mais 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 load garante que o código dentro do callback seja executado apenas após o carregamento total da página, independentemente de onde o script esteja posicionado. Isso é útil para inicialização não crítica que deve aguardar até que tudo o mais esteja pronto.
Verifique suas alterações
Depois de mover os scripts do footer para defer no <head>, verifique o impacto com o Real User Monitoring. O seu FCP e LCP devem melhorar. Nos sites monitorados pelo CoreDash, as origens que usam defer para a maioria dos seus scripts têm uma mediana de FCP 18% mais rápida do que as origens que ainda dependem do posicionamento no footer.
Fiz o CoreDash pras minhas próprias auditorias.
Menos de 1KB. Hospedado na UE. Sem banner de cookies. Agora com suporte a MCP.
Testa o CoreDash grátis
