Skip to main content
Validação HTML

O elemento “script” não deve ter o atributo “defer” a menos que o atributo “src” também seja especificado.

Sobre este problema HTML

Os atributos booleanos defer e async controlam como e quando um script externo é descarregado e executado em relação à análise HTML. Estes atributos existem especificamente para otimizar o carregamento de recursos externos. Um bloco <script> inline (um sem atributo src) não precisa de ser “descarregado” — o seu conteúdo já está incorporado no documento HTML. Por isso, o atributo defer não tem qualquer efeito significativo em scripts inline, e a especificação HTML proíbe explicitamente esta combinação.

De acordo com o padrão HTML living da WHATWG, o atributo defer “não deve ser especificado se o atributo src não estiver presente.” Os navegadores simplesmente ignoram o atributo defer em scripts inline, o que significa que o script irá executar sincronamente como se defer nunca tivesse sido adicionado. Isto pode induzir os programadores em erro, fazendo-os pensar que a execução do script inline está a ser diferida quando não está, causando potencialmente bugs de temporização subtis que são difíceis de diagnosticar.

A mesma regra aplica-se ao atributo async — também requer a presença de um atributo src para ser válido.

Como corrigir

Tem duas opções dependendo da sua situação:

  1. Se o script deve ser diferido, mova o código inline para um ficheiro .js externo e faça referência ao mesmo com o atributo src juntamente com defer.
  2. Se o script deve permanecer inline, remova completamente o atributo defer. Se precisar de execução diferida para código inline, considere colocar o elemento <script> no final do <body>, ou use DOMContentLoaded para esperar que o documento termine de ser analisado.

Exemplos

❌ Inválido: defer num script inline

<script defer>
  console.log("hello");
</script>

Isto gera o erro de validação porque defer está presente sem um atributo src correspondente.

✅ Opção de correção 1: adicionar um atributo src

Mova o JavaScript para um ficheiro externo (por exemplo, app.js) e faça referência ao mesmo:

<script defer src="app.js"></script>

O navegador irá descarregar app.js em paralelo com a análise HTML e executá-lo apenas depois de o documento ser completamente analisado.

✅ Opção de correção 2: remover defer do script inline

Se o script deve permanecer inline, simplesmente remova o atributo defer:

<script>
  console.log("hello");
</script>

✅ Opção de correção 3: usar DOMContentLoaded para execução inline diferida

Se precisar que o seu script inline espere até que o DOM esteja pronto, envolva o código num event listener DOMContentLoaded:

<script>
  document.addEventListener("DOMContentLoaded", function() {
    console.log("DOM is fully parsed");
  });
</script>

Isto consegue um efeito semelhante ao defer mas é válido para scripts inline.

❌ Inválido: async num script inline

A mesma regra aplica-se ao async:

<script async>
  document.title = "Updated";
</script>

✅ Corrigido

<script async src="update-title.js"></script>

Ou simplesmente remova async se o script for inline:

<script>
  document.title = "Updated";
</script>

Encontre problemas como este automaticamente

O Rocket Validator analisa milhares de páginas em segundos, detetando problemas HTML em todo o seu site.

Ajude-nos a melhorar os nossos guias

Este guia foi útil?

Pronto para validar os seus sites?
Comece o seu teste gratuito hoje.