Skip to main content
Validación HTML

El elemento “script” no debe tener el atributo “defer” a menos que también se especifique el atributo “src”.

Acerca de este problema HTML

Los atributos booleanos defer y async controlan cómo y cuándo se obtiene y ejecuta un script externo en relación con el parseo de HTML. Estos atributos existen específicamente para optimizar la carga de recursos externos. Un bloque <script> inline (uno sin atributo src) no necesita ser “descargado” — su contenido ya está incrustado en el documento HTML. Debido a esto, el atributo defer no tiene ningún efecto significativo en scripts inline, y la especificación HTML prohíbe explícitamente esta combinación.

Según el estándar vivo HTML de WHATWG, el atributo defer “no debe especificarse si el atributo src no está presente.” Los navegadores simplemente ignorarán el atributo defer en scripts inline, lo que significa que el script se ejecutará sincrónicamente como si defer nunca hubiera sido añadido. Esto puede confundir a los desarrolladores haciéndoles pensar que la ejecución de su script inline se está aplazando cuando no es así, causando potencialmente errores sutiles de sincronización que son difíciles de diagnosticar.

La misma regla se aplica al atributo async — también requiere la presencia de un atributo src para ser válido.

Cómo solucionarlo

Tienes dos opciones dependiendo de tu situación:

  1. Si el script debe ser aplazado, mueve el código inline a un archivo .js externo y refiérelo con el atributo src junto con defer.
  2. Si el script debe permanecer inline, elimina el atributo defer completamente. Si necesitas ejecución aplazada para código inline, considera colocar el elemento <script> al final del <body>, o usa DOMContentLoaded para esperar a que el documento termine de parsearse.

Ejemplos

❌ Inválido: defer en un script inline

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

Esto activa el error de validación porque defer está presente sin un atributo src correspondiente.

✅ Opción de solución 1: Añadir un atributo src

Mueve el JavaScript a un archivo externo (ej., app.js) y refiérelo:

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

El navegador descargará app.js en paralelo con el parseo de HTML y lo ejecutará solo después de que el documento esté completamente parseado.

✅ Opción de solución 2: Eliminar defer del script inline

Si el script debe permanecer inline, simplemente elimina el atributo defer:

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

✅ Opción de solución 3: Usar DOMContentLoaded para ejecución inline aplazada

Si necesitas que tu script inline espere hasta que el DOM esté listo, envuelve el código en un event listener de DOMContentLoaded:

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

Esto logra un efecto similar a defer pero es válido para scripts inline.

❌ Inválido: async en un script inline

La misma regla se aplica a async:

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

✅ Solucionado

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

O simplemente elimina async si el script es inline:

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

Encuentra problemas como este automáticamente

Rocket Validator escanea miles de páginas en segundos, detectando problemas de HTML en todo tu sitio web.

Ayúdanos a mejorar nuestras guías

¿Te ha sido útil esta guía?

¿Listo para validar tus sitios?
Inicia tu prueba gratuita hoy.