Você cola no functions.php um snippet que promete deixar tudo mais rápido, ativa o carregamento assíncrono WordPress, roda o PageSpeed e o número melhora. No dia seguinte, o cliente liga: o botão de adicionar ao carrinho não responde e o slider da home aparece desmontado. O culpado quase sempre é o mesmo: async aplicado a um script que dependia de outro para existir.
O problema não é a técnica, é a receita de “ative async em tudo”. Cada arquivo JavaScript do site tem um nível diferente de dependência. Portanto, tratar todos igual quebra justamente os componentes que geram receita.
Carregamento assíncrono WordPress: async, defer e o que cada um faz
Sem atributo, o navegador para de montar a página quando encontra um <script src="...">, baixa o arquivo e só depois segue. Isso é o comportamento padrão e é o que trava a renderização.
Com async, o download acontece em paralelo e o script executa assim que chega, mesmo que o HTML ainda esteja sendo lido. A ordem entre scripts async não é garantida. Se o script A precisa do B, async é uma aposta.
Com defer, o download também é paralelo, mas a execução só acontece depois que o HTML terminou de ser analisado, e na ordem em que os scripts aparecem. É o atributo mais seguro para a maioria dos casos.
| Atributo | Quando baixa | Quando executa | Mantém ordem? |
|---|---|---|---|
| nenhum | imediato, bloqueando | na hora | sim |
| async | em paralelo | assim que chega | não |
| defer | em paralelo | após o HTML | sim |
A documentação da MDN sobre o elemento script detalha esse comportamento. Vale ler antes de sair aplicando atributo em tudo.
O critério de decisão por script
Antes de escolher entre async e defer, responda três perguntas para cada arquivo:
- Esse script depende de outro para funcionar?
- Ele manipula algo que já precisa existir no DOM quando roda?
- Ele é chamado por um evento do usuário (clique, scroll, submit)?
Se a resposta for “sim” para qualquer uma, async está fora. O caminho é defer ou nenhum dos dois.
O que pode receber async
Scripts independentes, que não conversam com outros arquivos e não precisam do DOM pronto. Exemplos típicos:
- Tags de analytics e pixels de rastreamento.
- Widgets de chat e mapas carregados em iframe.
- Scripts de teste A/B que rodam isolados.
- Fontes de ícones carregadas via JS.
Mesmo nesses casos, se o script escreve algo na página (como um pixel que insere uma imagem), prefira defer para não competir com a renderização.
O que só aceita defer
Aqui está a maior parte do JavaScript de um tema WordPress:
- Scripts de menu, dropdown e accordion.
- Lazy loading de imagens.
- Validação de formulários de contato.
- Scripts de comentários e navegação por AJAX.
Todos precisam do HTML montado para funcionar. Com defer, eles executam depois da análise do documento, na ordem correta, e o efeito visual é praticamente o mesmo do async em termos de métrica de renderização.
O que nunca pode ser adiado
Esta é a lista que quebra o site quando ignorada:
- jQuery e dependências registradas no WordPress. O core registra jQuery como dependência de dezenas de scripts. Se o jQuery carrega depois de quem depende dele, o console enche de “$ is not a function”.
- Scripts do WooCommerce. O arquivo
cart-fragments.jse oadd-to-cart.jsatualizam o carrinho em tempo real. Adiar sem critério faz o mini-carrinho parar de atualizar. - Bibliotecas de slider e carrossel. Swiper, Slick e afins inicializam no carregamento e dependem da ordem dos arquivos.
- Scripts de checkout e pagamento. Qualquer coisa entre o clique em “finalizar compra” e a confirmação do pedido.
- Scripts inline que dependem de um arquivo externo. O WordPress imprime muita coisa inline via
wp_add_inline_script. Se o externo for adiado, o inline quebra.
Em lojas, o impacto é direto em conversão. Antes de mexer em scripts de carrinho, vale revisar a segurança do WooCommerce antes de vender, porque qualquer alteração em checkout precisa de teste em ambiente separado.
Como aplicar no WordPress sem plugin duvidoso
Existem plugins que fazem isso, mas muitos aplicam async em tudo e causam exatamente o problema descrito. O caminho mais controlado é filtrar cada script pelo handle.
O WordPress tem o filtro script_loader_tag, que permite alterar a tag gerada. Um exemplo de uso seguro, aplicando defer apenas a um handle específico:
add_filter( 'script_loader_tag', function( $tag, $handle ) {
if ( 'meu-script-especifico' === $handle ) {
return str_replace( ' src', ' defer src', $tag );
}
return $tag;
}, 10, 2 );
Para descobrir o handle de cada script, inspecione o HTML gerado ou use um plugin de listagem. Nunca aplique o filtro em todos os handles de uma vez.
Ordem de teste em produção
Não replique a mudança direto em todos os sites. A ordem abaixo reduz o risco:
- Escolha um site piloto com tráfego baixo e faça backup do banco e dos arquivos.
- Aplique defer em um único handle por vez.
- Abra o site em janela anônima e verifique o console do navegador.
- Teste o fluxo completo: home, página interna, formulário, carrinho e checkout.
- Rode uma medição de velocidade antes e depois.
- Só então replique nos demais sites, um por vez.
Se você administra vários sites, esse ciclo se repete em cada um, e é aí que a gestão manual começa a falhar. Um painel como o 100% WP ajuda a manter backup e monitoramento padronizados entre sites, o que torna o teste piloto mais seguro.
Para medir o efeito real da mudança, o ideal é comparar métricas antes e depois. O artigo sobre medir velocidade de carregamento em vários sites mostra como padronizar essa comparação.
Quando NÃO usar essa solução
Adiar scripts não é a primeira coisa a fazer em um site lento. Existem cenários em que o ganho é pequeno e o risco é grande:
- Site com TTFB alto. Se o servidor demora para responder, adiar JavaScript não resolve. O gargalo está antes.
- Site com muitas imagens pesadas. O maior peso costuma estar nas imagens, não no JS. Nesse caso, otimizar imagens em vários sites traz mais resultado.
- Tema ou plugin que já faz isso. Alguns temas aplicam defer por conta própria. Aplicar de novo pode duplicar o atributo.
- Site sem ambiente de teste. Sem staging, qualquer erro vai direto para o cliente. Nesse caso, espere ter um ambiente seguro.
Antes de mexer em scripts, vale identificar onde está o gargalo real. O guia sobre achar o gargalo antes de instalar cache ajuda a não tratar sintoma como causa.
Erros comuns
- Aplicar async em todos os scripts via filtro global.
- Adiar jQuery sem checar quem depende dele.
- Esquecer scripts inline que dependem de um externo.
- Testar só a home e não o checkout.
- Replicar a mudança em todos os sites sem validar em um piloto.
- Confiar só no PageSpeed e ignorar o comportamento real do usuário.
O erro mais caro é o último item combinado com o primeiro: a métrica melhora, o carrinho quebra e o prejuízo só aparece no fim do mês.
Prevenção
Algumas práticas reduzem o risco de forma consistente:
- Mantenha um site piloto com a mesma stack dos demais.
- Documente quais handles receberam defer e por quê.
- Tenha backup recente antes de qualquer alteração em functions.php.
- Monitore o console do navegador após cada mudança.
- Rode uma checagem automática de performance depois de cada deploy.
Se você gerencia muitos sites, uma checagem automática de performance em vários sites evita que uma regressão passe despercebida por semanas.
Quando chamar alguém
Se o site tem carrinho, assinaturas ou checkout e você não tem ambiente de teste, o custo de errar é alto. Nesse caso, faz sentido chamar quem já fez esse tipo de ajuste antes. O serviço de otimização de site lento cobre diagnóstico e aplicação controlada, sem quebrar o que já funciona.
Por fim, o carregamento assíncrono WordPress não é uma chave liga/desliga. É uma decisão por script, com teste em produção e ordem definida. Feito assim, o ganho é real e o risco é pequeno.


