Carga asíncrona: async vs defer y rendimiento
La carga asíncrona obtiene recursos sin bloquear la página. Cómo funcionan los scripts async y defer, import() y las imágenes lazy, y los errores típicos.
¿Qué es la carga asíncrona?
La carga asíncrona consiste en obtener un recurso sin impedir que el navegador haga otras tareas, como analizar el HTML o renderizar. En la web incluye los scripts async y defer, el import() dinámico, las imágenes con carga diferida y las peticiones fetch. La página sigue respondiendo mientras llega el recurso y lo usa cuando está listo.
async vs defer
Un script clásico sin ninguno de los dos atributos se descarga y ejecuta de inmediato, y el navegador detiene el análisis de la página mientras tanto. async y defer descargan el script en paralelo al análisis. Se diferencian en cuándo se ejecuta.
- async: se ejecuta en cuanto termina de descargarse, lo que puede pausar el análisis, y no garantiza el orden entre scripts.
- defer: se ejecuta cuando el documento ya está analizado, antes de
DOMContentLoaded, y en el orden en que aparecen los scripts en la página. - type="module": se difiere por defecto, así que
deferno tiene efecto.
Ambos atributos solo funcionan en scripts con src; en scripts en línea no hacen nada. Si se ponen los dos, prevalece async. Fuente: MDN, el elemento script.
Ejemplo
<!-- classic script, blocks parsing -->
<script src="app.js"></script>
<!-- downloads in parallel, runs when ready, any order -->
<script async src="analytics.js"></script>
<!-- downloads in parallel, runs after parsing, in order -->
<script defer src="app.js"></script>
<!-- module scripts are deferred by default -->
<script type="module" src="main.js"></script>Un reparto habitual: defer para el código de tu app, que depende del DOM y de otros scripts, y async para scripts de terceros independientes, como la analítica.
Otras formas de carga asíncrona
- Importación dinámica:
import()carga un módulo ES bajo demanda y devuelve una promesa. Es la base de la división de código, donde un fragmento se carga solo cuando hace falta. - Imágenes e iframes diferidos:
loading="lazy"pospone los recursos fuera de pantalla hasta que el usuario se acerca al hacer scroll. Consulta la carga diferida (lazy loading). - Peticiones de datos: llamadas
fetchy XHR que rellenan la página después del primer renderizado.
Errores comunes
- async en scripts que dependen entre sí. El orden no está garantizado, así que un plugin puede ejecutarse antes que su biblioteca.
- Diferir la imagen principal. El elemento más grande visible suele ser el que mide el Largest Contentful Paint, así que diferirlo retrasa la métrica. Difiere solo lo que empieza fuera de pantalla.
- Scripts bloqueantes en el head. Retienen la ruta crítica de renderizado. Difiérelos salvo que el primer pintado los necesite.
- Contenido que aparece tarde y mueve el diseño. Reserva espacio para el contenido cargado de forma asíncrona.
- Sin gestión de errores. Un
import()ofetchfallido rechaza su promesa; trátalo o la función nunca aparecerá sin avisar.
Carga asíncrona, testing y monitorización
La carga asíncrona mejora lo que el usuario ve primero, pero traslada el trabajo en lugar de eliminarlo. Los scripts siguen descargándose y ejecutándose, así que mide el resultado en el navegador con tiempos de DOM listo y Core Web Vitals, no solo con tiempos de respuesta del servidor. Nuestra guía de rendimiento de JavaScript muestra cómo async, defer y la división de código afectan al hilo principal, y la monitorización de velocidad de página sigue el efecto de cada cambio de forma programada.
Preguntas frecuentes sobre la carga asíncrona
¿Cuál es la diferencia entre async y defer?
Ambos descargan el script sin bloquear el analizador. async lo ejecuta en cuanto llega, sin orden garantizado. defer lo ejecuta tras el análisis, antes de DOMContentLoaded, en el orden del documento.
¿Cuál debo usar?
Usa defer para scripts que necesitan el DOM o dependen unos de otros. Usa async para scripts independientes, como la analítica, que pueden ejecutarse cuando lleguen.
¿async y defer funcionan en scripts en línea?
No. Sin atributo src no tienen efecto. Los scripts de módulo se difieren por defecto.
¿La carga asíncrona hace más rápida una página?
Normalmente mejora lo pronto que se renderiza y se puede usar, porque no se detiene el analizador. El trabajo total es el mismo, así que comprueba el efecto con mediciones reales.
¿La carga diferida es lo mismo que la carga asíncrona?
La carga diferida es un tipo de ella: el recurso se obtiene solo cuando hace falta, por ejemplo cuando una imagen se acerca a la pantalla. Los scripts async se obtienen enseguida, solo que sin bloquear la página.
Términos relacionados
- ¿Qué es Continuous Delivery (CD)?
- ¿Qué es la computación periférica?
- Qué es Expo: framework de React Native, EAS Build y actualizaciones
- Hot Module Replacement (HMR): cómo funciona
- Regeneración estática incremental (ISR)
- Infraestructura como código (IaC): definición, herramientas, ejemplos
- ¿Qué es Jamstack?
- Markdown
Herramientas LoadFocus relacionadas
Lleva este concepto a la práctica con LoadFocus, la misma plataforma que potencia todo lo que acabas de leer.