Defer vs Async JavaScript y cómo esto afecta a las Core Web Vitals

Aprende cuándo usar async y cuándo usar defer en JavaScript para obtener los mejores resultados de Core Web Vitals

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-03-27

Defer vs Async JavaScript y cómo esto afecta a las Core Web Vitals

Siempre que audito las Core Web Vitals de un cliente, a menudo encuentro que hay poca distinción en una página entre el JavaScript que bloquea el analizador (sync), asíncrono o diferido. Es una lástima porque los diferentes scripts tienen distintos tiempos óptimos.

Última revisión por Arjen Karel en marzo de 2026

Según el Web Almanac de 2025, solo el 15% de las páginas móviles superan la auditoría de recursos que bloquean el renderizado. La página mediana carga 22 scripts que suman más de 630 KB, con 251 KB de ese JavaScript que no se utilizan en absoluto. La mayoría de los sitios cargan demasiado JavaScript, y lo cargan en el momento equivocado.

En resumen

El JavaScript 'normal' en el head de la página bloquea al navegador para que no analice el HTML hasta que se descargue y ejecute. Los scripts Async se descargan en segundo plano pero se ejecutan tan pronto como están listos, lo que aún puede interrumpir el análisis. Los scripts Deferred se descargan en segundo plano y esperan hasta que se complete el análisis antes de ejecutarse, en el orden del documento.

Usa defer para cualquier cosa que toque el DOM. Usa async para scripts que sean completamente independientes (analíticas, píxeles de seguimiento). No uses ninguno (sync) solo si el script debe ejecutarse antes de que se renderice la página. Ante la duda, usa defer.

1. JavaScript síncrono (sync)

Por defecto, los scripts en el head de la página son síncronos. Cuando el navegador encuentra un script síncrono, detiene el análisis del HTML, descarga el script y lo ejecuta antes de continuar. Esto significa que no se pintan píxeles hasta que terminan todos los scripts síncronos. Para scripts grandes o lentos, esto crea un retraso visible en el First Contentful Paint.

<!DOCTYPE html>
<html>
<head>
  <title>Sync JavaScript Example</title>
  <script src="script1.js"></script>
  <script src="script2.js"></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

El navegador debe descargar y ejecutar script1.js antes de siquiera empezar con script2.js. Mientras tanto, no se renderiza nada. La página móvil mediana ya tiene un Total Blocking Time de casi 2 segundos en 2025. Los scripts síncronos en el head empeoran esto.

2. JavaScript asíncrono (async)

Añadir el atributo async le dice al navegador que descargue el script en segundo plano mientras continúa analizando el HTML. El script se ejecuta tan pronto como termina de descargarse, dondequiera que esté el analizador en ese momento. El análisis solo se pausa durante la ejecución.

<!DOCTYPE html>
<html>
<head>
  <title>Async JavaScript Example</title>
  <script src="script1.js" async></script>
  <script src="script2.js" async></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

Los scripts async no garantizan el orden de ejecución. El script que termine de descargarse primero se ejecuta primero. Si script2.js depende de script1.js, async romperá las cosas de forma impredecible. Usa async solo para scripts que sean completamente independientes entre sí y del DOM.

Una cosa a tener en cuenta: en Chrome, los scripts async obtienen una baja prioridad de red por defecto. Esto significa que el navegador puede empezar a descargarlos más tarde de lo que esperas. Si necesitas que un script async se cargue rápidamente (sin bloquear el análisis), añade fetchpriority="high".

3. JavaScript diferido (defer)

El atributo defer también descarga el script en segundo plano, pero la ejecución se pospone hasta que el documento HTML se analiza por completo. Los scripts diferidos se ejecutan en el orden del documento, justo antes de que se dispare el evento DOMContentLoaded.

<!DOCTYPE html>
<html>
<head>
  <title>Defer JavaScript Example</title>
  <script src="script1.js" defer></script>
  <script src="script2.js" defer></script>
</head>
<body>
  <!-- Page content here -->
</body>
</html>

Defer es la opción más segura para la mayoría de los scripts. El DOM está completamente disponible cuando se ejecuta el script, se mantiene el orden de ejecución y el primer renderizado no se bloquea. The Telegraph difirió todos sus scripts y mejoró el tiempo de carga de anuncios en 4 segundos.

4. Scripts de módulo (Module scripts)

Si usas módulos ES (<script type="module">), obtienes el comportamiento defer automáticamente. Los scripts de módulo se descargan en segundo plano, se ejecutan después del análisis y mantienen el orden. Añadir defer explícitamente no tiene ningún efecto porque ya es el comportamiento predeterminado.

Puedes añadir async a un script de módulo si quieres que se ejecute tan pronto como se resuelva su gráfico de dependencias, en lugar de esperar a que se complete el análisis.

Tabla comparativa

Atributo Descarga Ejecución ¿Bloquea el análisis? ¿Mantiene el orden?
none (sync) Bloquea el análisis durante la descarga Inmediatamente después de la descarga Sí (descarga + ejecución)
async En segundo plano Tan pronto como se completa la descarga Solo durante la ejecución No
defer En segundo plano Después de analizar el HTML, antes de DOMContentLoaded No
type="module" En segundo plano Después de analizar el HTML (igual que defer) No

Preguntas comunes

¿Qué pasa si uso async y defer en la misma etiqueta? Async gana. El atributo defer se ignora por completo. Este patrón solía existir como un fallback para IE9, pero en 2026 no hay razón para usar ambos.

¿Funcionan async y defer en scripts en línea? No. Ambos atributos se ignoran en los scripts en línea clásicos (sin src). Solo funcionan en scripts externos. La excepción es <script type="module">, que se difiere por defecto incluso cuando está en línea.

¿Es mejor defer que poner los scripts al final del body? Sí. Un script diferido en el <head> comienza a descargarse inmediatamente (en paralelo con el análisis HTML). Un script al final del body no puede empezar a descargarse hasta que el analizador llega a él. Defer te da un descubrimiento más temprano y una ejecución más tardía, que es lo mejor de ambos mundos.

Cómo afectan async y defer a las Core Web Vitals

Los scripts síncronos perjudican directamente al FCP porque nada se pinta hasta que terminan. También perjudican al LCP si el elemento LCP no puede renderizarse hasta que se completen los scripts.

Los scripts async mejoran el FCP (el primer renderizado no se bloquea por la descarga) pero aún pueden causar problemas de INP si se ejecutan durante la interacción del usuario y bloquean el hilo principal.

Los scripts deferidos te dan las mejores métricas de renderizado porque no interfieren en absoluto con el renderizado inicial. La compensación: si tu página depende de JavaScript para mostrar contenido (single-page apps), defer en realidad puede retrasar el LCP porque el contenido no aparece hasta que el script se ejecuta después del análisis.

En los datos de monitorización de CoreDash, los sitios que movieron todos los scripts no críticos de sync a defer vieron mejorar su FCP en 340ms en promedio.

Yendo un paso más allá: cargar scripts bajo demanda

Async y defer pueden acelerar una página al no bloquear el analizador, pero es importante tener en cuenta que diferir los scripts no resolverá todos tus problemas. Por ejemplo, el elemento Largest Contentful Paint es vulnerable a la competencia de red y CPU causada por los scripts diferidos y asíncronos. El Interaction to Next Paint también se ve afectado por los scripts que se ejecutan temprano durante la carga de la página. Por eso, siempre que sea posible, debes cargar los scripts bajo demanda para tener más control sobre su impacto en el rendimiento de la página. Lee cómo cargamos scripts bajo demanda.

Para una descripción completa de todas las estrategias de carga de JavaScript, consulta 16 métodos para diferir JavaScript. Si estás lidiando con la advertencia de recursos que bloquean el renderizado de Lighthouse, esa guía cubre la solución. También puedes ajustar la carga con los niveles de prioridad de JavaScript y elegir la ubicación óptima del script en el head frente al footer.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

I built CoreDash for my own audits.

Under 1KB. EU hosted. No consent banner. Now with MCP support.

Try CoreDash free
Defer vs Async JavaScript y cómo esto afecta a las Core Web VitalsCore Web Vitals Defer vs Async JavaScript y cómo esto afecta a las Core Web Vitals