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.
Search Console reclamou do seu site?
Entrego uma lista priorizada de fixes baseada em dados de campo. Não um PDF de 50 páginas.
Solicitar auditoria