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

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-03

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

  1. 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.
  2. 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.
  3. 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

  1. 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 use defer ou async em scripts externos no head para evitar isso.
  2. 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

  1. Não bloqueio por padrão: Scripts no footer não bloqueiam a renderização inicial porque o HTML acima deles já foi processado.
  2. 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

  1. 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.
  2. 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 o defer ter 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:

  1. 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> sem defer se 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.
  2. Scripts importantes: Scripts cruciais para conversão ou interação (formulários, navegação, consentimento de cookies). Coloque no <head> com defer ou async.
  3. Scripts normais: Scripts que não afetam a primeira renderização da página (carrosséis, modais, abas). Coloque no <head> com defer.
  4. 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 load ou requestIdleCallback. 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.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

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
JavaScript no Head vs Footer: Como Isso Afeta os Core Web VitalsCore Web Vitals JavaScript no Head vs Footer: Como Isso Afeta os Core Web Vitals