JavaScript Defer vs Async e como isso afeta os Core Web Vitals
Aprenda quando usar async ou defer no JavaScript para obter os melhores resultados nos Core Web Vitals

JavaScript Defer vs Async e como isso afeta os Core Web Vitals
Sempre que audito os Core Web Vitals de um cliente, frequentemente descubro que há pouca distinção em uma página entre JavaScript que bloqueia o parser (sync), assíncrono ou deferido (deferred). Isso é uma pena, porque diferentes scripts têm diferentes tempos de execução ideais.
Última revisão por Arjen Karel em março de 2026
Table of Contents!
- JavaScript Defer vs Async e como isso afeta os Core Web Vitals
- Em resumo
- 1. JavaScript Síncrono (sync)
- 2. JavaScript Assíncrono (async)
- 3. JavaScript Deferido (defer)
- 4. Module scripts
- Tabela de comparação
- Perguntas frequentes
- Como async e defer afetam os Core Web Vitals
- Indo um passo além: carregue scripts sob demanda
De acordo com o Web Almanac de 2025, apenas 15% das páginas mobile passam na auditoria de recursos de bloqueio de renderização (render-blocking). A página mediana carrega 22 scripts totalizando mais de 630 KB, com 251 KB desse JavaScript sendo completamente não utilizados. A maioria dos sites está carregando JavaScript em excesso, e no momento errado.
Em resumo
O JavaScript 'normal' no head da página bloqueia o navegador de fazer o parse do HTML até que seja baixado e executado. Scripts async são baixados em segundo plano, mas executados assim que estão prontos, o que ainda pode interromper o parser. Scripts deferidos (defer) são baixados em segundo plano e esperam até que o parse do HTML esteja concluído antes de serem executados, na ordem do documento.
Use defer para qualquer coisa que manipule o DOM. Use async para scripts que são completamente independentes (analytics, pixels de rastreamento). Não use nenhum dos dois (sync) apenas se o script precisar ser executado antes da página renderizar. Em caso de dúvida, use defer.

1. JavaScript Síncrono (sync)
Por padrão, scripts no head da página são síncronos. Quando o navegador encontra um script síncrono, ele para de fazer o parse do HTML, baixa o script e o executa antes de continuar. Isso significa que nenhum pixel é pintado até que todos os scripts sync terminem. Para scripts grandes ou lentos, isso cria um atraso visível no First Contentful Paint.
<!DOCTYPE html> <html> <head> <title>Sync JavaScript Example</title> <script src="script1.js"></script> <script src="script2.js"></script> </head> <body> <!-- Page content here --> </body> </html>
O navegador deve baixar e executar o script1.js antes mesmo de começar o script2.js. Enquanto isso, nada é renderizado. A página mobile mediana já possui um Total Blocking Time de quase 2 segundos em 2025. Scripts síncronos no head pioram essa situação.
2. JavaScript Assíncrono (async)
Adicionar o atributo async diz ao navegador para baixar o script em segundo plano enquanto continua a fazer o parse do HTML. O script é executado assim que termina o download, onde quer que o parser esteja naquele momento. O parse é pausado apenas durante a execução.
<!DOCTYPE html> <html> <head> <title>Async JavaScript Example</title> <script src="script1.js" async></script> <script src="script2.js" async></script> </head> <body> <!-- Page content here --> </body> </html>
Scripts async não garantem a ordem de execução. Qualquer script que terminar de baixar primeiro será executado primeiro. Se script2.js depende de script1.js, o uso de async quebrará as coisas de forma imprevisível. Use async apenas para scripts que sejam completamente independentes uns dos outros e do DOM.
Um detalhe importante: no Chrome, scripts async recebem Baixa prioridade de rede (Low network priority) por padrão. Isso significa que o navegador pode começar a baixá-los mais tarde do que você espera. Se você precisa que um script async carregue rapidamente (sem bloquear o parse), adicione fetchpriority="high".
3. JavaScript Deferido (defer)
O atributo defer também baixa o script em segundo plano, mas a execução é adiada até que o documento HTML seja totalmente analisado (parsed). Scripts deferidos são executados na ordem do documento, logo antes de o evento DOMContentLoaded ser disparado.
<!DOCTYPE html> <html> <head> <title>Defer JavaScript Example</title> <script src="script1.js" defer></script> <script src="script2.js" defer></script> </head> <body> <!-- Page content here --> </body> </html>
O defer é a escolha mais segura para a maioria dos scripts. O DOM está totalmente disponível quando o script é executado, a ordem de execução é preservada e o primeiro paint não é bloqueado. O Telegraph deferiu todos os seus scripts e melhorou o tempo de carregamento dos anúncios em 4 segundos.
4. Module scripts
Se você usa ES modules (<script type="module">), você obtém o comportamento de defer automaticamente. Module scripts são baixados em segundo plano, executam após o parse e mantêm a ordem. Adicionar defer explicitamente não tem efeito, pois ele já é o padrão.
Você pode adicionar async a um module script se quiser que ele seja executado assim que sua árvore de dependências for resolvida, em vez de esperar a conclusão do parse.
Tabela de comparação
| Atributo | Download | Execução | Bloqueia o parser? | Preserva a ordem? |
|---|---|---|---|---|
nenhum (sync) |
Bloqueia o parser durante o download | Imediatamente após o download | Sim (download + execução) | Sim |
async |
Em segundo plano | Assim que o download é concluído | Apenas durante a execução | Não |
defer |
Em segundo plano | Após o parse do HTML, antes do DOMContentLoaded | Não | Sim |
type="module" |
Em segundo plano | Após o parse do HTML (igual ao defer) | Não | Sim |
Perguntas frequentes
E se eu usar tanto async quanto defer na mesma tag? O async ganha. O atributo defer é totalmente ignorado. Esse padrão costumava existir como um fallback para o IE9, mas em 2026 não há motivo para usar ambos.
Async e defer funcionam em scripts inline? Não. Ambos os atributos são ignorados em scripts inline clássicos (sem src). Eles funcionam apenas em scripts externos. A exceção é <script type="module">, que é deferido por padrão, mesmo sendo inline.
Usar defer é melhor do que colocar scripts no final do body? Sim. Um script deferido no <head> começa a baixar imediatamente (em paralelo com o parse do HTML). Um script no final do body não pode começar a baixar até que o parser chegue até ele. O defer oferece descoberta antecipada e execução posterior, o que é o melhor dos dois mundos.
Como async e defer afetam os Core Web Vitals
Scripts síncronos prejudicam diretamente o FCP porque nada é pintado até que eles terminem. Eles também prejudicam o LCP se o elemento de LCP não puder renderizar até que os scripts sejam concluídos.
Scripts async melhoram o FCP (o primeiro paint não é bloqueado pelo download), mas ainda podem causar problemas no INP se forem executados durante a interação do usuário e bloquearem a main thread.
Scripts deferidos (defer) oferecem as melhores métricas de paint porque não interferem de forma alguma na renderização inicial. A desvantagem: se a sua página depende de JavaScript para exibir conteúdo (single-page apps), o defer pode, na verdade, atrasar o LCP, porque o conteúdo não aparece até que o script seja executado após o parse.
Nos dados de monitoramento do CoreDash, os sites que moveram todos os scripts não críticos de sync para defer viram seu FCP melhorar em 340 ms em média.
Indo um passo além: carregue scripts sob demanda
Async e defer podem acelerar uma página por não bloquearem o parser, mas é importante notar que deferir scripts não resolverá todos os seus problemas. Por exemplo, o elemento do Largest Contentful Paint é vulnerável à competição de rede e CPU causada por scripts deferidos e async. O Interaction to Next Paint também é afetado por scripts que executam cedo durante o carregamento da página. É por isso que, sempre que possível, você deve carregar scripts sob demanda para ter mais controle sobre o impacto deles na performance da página. Leia como nós carregamos scripts sob demanda.
Para uma visão geral completa de todas as estratégias de carregamento de JavaScript, veja 16 métodos para deferir o JavaScript. Se você estiver lidando com o aviso do Lighthouse de recursos de bloqueio de renderização (render-blocking), esse guia cobre a solução. Você também pode ajustar o carregamento detalhadamente com os níveis de prioridade do JavaScript e escolher a colocação ideal do script no head vs footer.
Performance degrades the moment you stop watching.
I set up the monitoring, the budgets, and the processes. That is the difference between a fix and a solution.
Let's talk
