defer y async cambian cuándo descarga y ejecuta un <script> externo relativo al análisis del HTML. Ambos permiten descargar el script en paralelo sin bloquear el analizador — la diferencia está en el tiempo de ejecución.
html
defer y async cambian cuándo descarga y ejecuta un <script> externo relativo al análisis del HTML. Ambos permiten descargar el script en paralelo sin bloquear el analizador — la diferencia está en el tiempo de ejecución.
Normal: parse──stop──[download+exec]──parse──────── (slowest)
async: parse──────────────────exec──parse──────── (runs whenever it arrives)
defer: parse───────────────────────────parse──exec (after parsing, before DOMContentLoaded)
async | defer | |
|---|---|---|
| Descarga | paralela | paralela |
| Se ejecuta | tan pronto como se descarga | después de que el HTML se analiza completamente |
| ¿Se preserva el orden? | No (el que termine primero) | Sí (orden del documento) |
| ¿Bloquea el analizador? | solo brevemente durante la ejecución | nunca |
defer — para scripts que tocan el DOM o dependen entre sí/del orden (código de tu aplicación). Se ejecutan después de que el DOM existe, en secuencia, justo antes de DOMContentLoaded.async — para scripts de terceros independientes que no dependen del DOM u otros scripts (analytics, anuncios). El orden no importa, ejecútalos lo antes posible.<script src="analytics.js" async></script> <!-- independent → async -->
<script src="app.js" defer></script> <!-- app logic, ordered → defer -->
Nota: ambos aplican solo a scripts externos (src); se ignoran en scripts inline. Los módulos ES (type="module") son deferred por defecto.
Usar defer/async evita que los scripts bloqueen el análisis del HTML, lo que mejora directamente el rendimiento de carga y First Contentful Paint.
Elegir el correcto (defer para código de aplicación ordenado y dependiente del DOM, async para scripts de terceros sin seguimiento) evita tanto cargas lentas como errores de dependencia de orden.