W3docs

Scripts: async, defer

Saiba como os atributos async e defer controlam o carregamento de scripts JavaScript, evitando bloqueios no HTML e melhorando o desempenho da página.

O local onde você coloca um <script> e a forma como o carrega têm um efeito direto na velocidade com que sua página fica utilizável. Por padrão, scripts podem paralisar o navegador no meio da renderização; os atributos async e defer permitem que você instrua o navegador a baixar o JavaScript em segundo plano. Este artigo explica como os scripts de bloqueio simples se comportam, o que async e defer mudam, por que scripts de módulo são adiados automaticamente e como escolher a opção certa para cada script.

Como um script simples bloqueia o parsing

Um <script> sem async ou defer é bloqueador de renderização. Quando o parser HTML encontra a tag, ele para de construir a página, busca o script (se tiver um src), executa-o até o fim e só então retoma o parsing do restante do documento:

<p>...content before script...</p>

<script src="big.js"></script> <!-- parsing pauses here until big.js downloads AND runs -->

<p>...content after script (the user can't see this yet)...</p>

Duas consequências surgem disso:

  • O script não consegue ver elementos DOM que aparecem depois dele, pois ainda não foram processados pelo parser.
  • O usuário fica olhando para uma página parcialmente construída enquanto o script é baixado. Em uma rede lenta, este é o clássico problema da "página em branco".

A solução histórica era colocar scripts no final do <body>. async e defer oferecem uma solução mais elegante: mantenha a tag no <head>, mas impeça que ela bloqueie.

Tanto async quanto defer afetam apenas scripts externos — eles exigem o atributo src. São ignorados em blocos <script> inline.

Entendendo o Atributo async

O que é o Atributo async?

Quando você adiciona o atributo async a uma tag <script>, instrui o navegador a baixar o script em segundo plano sem bloquear o parsing do HTML. Assim que o download termina, o navegador pausa o parsing, executa o script e então continua. Como os tempos de download variam, scripts async são executados assim que ficam prontos — em ordem imprevisível, possivelmente antes de o restante do documento ter sido processado.

Isso torna o async perfeito para scripts independentes que não dependem do DOM nem uns dos outros: analytics, anúncios e outros rastreadores do tipo "disparar e esquecer".

Exemplo de Código: Usando async

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Async Example</title>
</head>
<body>
    <h1>Testing Async</h1>
    <script async src="https://example.com/async-script.js"></script>
</body>
</html>

Benefícios e trade-offs do async

  • Sem bloqueio: O parsing do HTML continua enquanto o script é baixado.
  • Executa o mais cedo possível: O script é executado no momento em que o download termina — ideal para scripts independentes.
  • Sem ordem garantida: Com vários scripts async, o que baixar primeiro executa primeiro. Nunca use async para scripts que dependem uns dos outros.
  • Pode executar antes do DOM estar pronto: Pode ser executado antes do parsing terminar, portanto não presuma que elementos posteriores existam.

Aproveitando o Atributo defer

O que é o Atributo defer?

O atributo defer também baixa o script em segundo plano sem bloquear o parsing. A diferença está em quando ele é executado: um script adiado é executado somente após o documento HTML ter sido totalmente processado, e logo antes do evento DOMContentLoaded ser disparado. Scripts com defer também mantêm sua ordem no documento — a primeira tag defer sempre executa antes da segunda, independentemente de qual baixar primeiro.

Isso torna o defer o padrão correto para o código da sua aplicação: todo o DOM tem garantia de existir e os scripts dependentes permanecem em ordem.

Exemplo de Código: Usando defer

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Defer Example</title>
</head>
<body>
    <h1>Testing Defer</h1>
    <script defer src="https://example.com/defer-script.js"></script>
</body>
</html>

Benefícios do Uso do defer

  • DOM Pronto: Todo o documento HTML é processado antes da execução do script.
  • Ordem Mantida: Os scripts executam na ordem do documento, o que é essencial para scripts que dependem uns dos outros.

Scripts de módulo são adiados por padrão

Um <script type="module"> se comporta como um script adiado automaticamente — você não precisa adicionar defer. Ele é buscado sem bloquear o parsing e executa após o documento ser processado, em ordem. Para fazer um módulo executar assim que estiver pronto (o comportamento do async), adicione async explicitamente:

<!-- Deferred automatically; runs after parsing, in order -->
<script type="module" src="app.js"></script>

<!-- Opt into async: runs as soon as it (and its imports) are ready -->
<script type="module" async src="tracker.js"></script>

Se você é novo em módulos, consulte a Introdução a Módulos.

async vs defer em resumo

Comportamentoasyncdefer
Bloqueia o parsing do HTML?NãoNão
Quando executa?Assim que o download terminaApós o parsing, antes do DOMContentLoaded
Ordem de execuçãoO que baixar primeiro executa primeiroOrdem do documento, garantida
DOM totalmente disponível?Não garantidoSim
Melhor paraScripts independentes (analytics, anúncios)Código da aplicação, scripts dependentes

Uma regra simples:

  • Use async quando o script for independente — não depende de outros scripts nem do DOM.
  • Use defer quando o script precisar de todo o DOM ou quando a ordem de execução for importante.

Exemplo Prático: Decisões de Carregamento de Scripts

Considere carregar uma biblioteca utilitária (como o Lodash) mais um arquivo próprio que depende dela. Como a ordem importa aqui, defer é a escolha certa — ambos são baixados em segundo plano, mas executam em sequência após o parsing:

<script defer src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script defer src="script.js"></script>

Aqui lodash.min.js tem garantia de executar antes de script.js, e ambos aguardam até a página ser processada. Mudar esses scripts para async arriscaria script.js executar primeiro e falhar porque o Lodash ainda não foi carregado.

Para carregar recursos que não são scripts (imagens, estilos) e reagir ao seu sucesso ou falha, veja Carregamento de recursos: onload e onerror.

Conclusão

Usar efetivamente os atributos async e defer em tags de script é fundamental para o desenvolvimento web moderno. Ao entender e aplicar corretamente esses atributos, os desenvolvedores podem garantir carregamentos de página mais rápidos e uma melhor experiência para o usuário. O carregamento assíncrono de scripts trata de otimização de desempenho e da criação de aplicações web eficientes e centradas no usuário.

Prática

Prática
Quais são os usos dos atributos 'async' e 'defer' em JavaScript?
Quais são os usos dos atributos 'async' e 'defer' em JavaScript?
Was this page helpful?