0% encontró este documento útil (0 votos)
77 vistas6 páginas

Scripts Async, Defer

Los atributos async y defer de la etiqueta <script> permiten cargar scripts de forma asíncrona para evitar que bloqueen la renderización de la página web. Mientras async carga los scripts de forma independiente sin orden fijo, defer mantiene el orden relativo pero permite que la página se renderice antes de ejecutarlos. Los scripts dinámicos se comportan como async a menos que se establezca explícitamente async=false.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
77 vistas6 páginas

Scripts Async, Defer

Los atributos async y defer de la etiqueta <script> permiten cargar scripts de forma asíncrona para evitar que bloqueen la renderización de la página web. Mientras async carga los scripts de forma independiente sin orden fijo, defer mantiene el orden relativo pero permite que la página se renderice antes de ejecutarlos. Los scripts dinámicos se comportan como async a menos que se establezca explícitamente async=false.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 6

 Comprar EPUB/PDF 

ES

 → El navegador: Documentos, Eventos e Interfaces → El documento y carga de recursos

 12 de julio de 2022

Scripts: async, defer


En los sitios web modernos los scripts suelen ser más “pesados” que el HTML, el tamaño de la descarga es
grande y el tiempo de procesamiento es mayor.

Cuando el navegador carga el HTML y se encuentra con una etiqueta <script>...</script> , no puede
continuar construyendo el DOM. Debe ejecutar el script en el momento. Lo mismo sucede con los scripts
externos <script src="..."></script> , el navegador tiene que esperar hasta que el script sea
descargado, ejecutarlo y solo después procesa el resto de la página.

Esto nos lleva a dos importantes problemas:

1. Los scripts no pueden ver los elementos del DOM que se encuentran debajo de él por lo que no pueden
agregar controladores de eventos, etc.
2. Si hay un script muy pesado en la parte superior de la página, este “bloquea la página”. Los usuarios no
pueden ver el contenido de la página hasta que sea descargado y ejecutado.

 
1 <p>...contenido previo al script...</p>
2
3 <script src="https://javascript.info/article/script-async-defer/long.js?spee
4
5 <!-- Esto no es visible hasta que el script sea cargado -->
6 <p>...contenido posterior al script...</p>

Hay algunas soluciones para eso. Por ejemplo podemos poner el script en la parte inferior de la página por lo
que podrá ver los elementos sobre él y no bloqueará la visualización del contenido de la página.

1 <body>
2 ...todo el contenido está arriba del script...
3
4 <script src="https://javascript.info/article/script-async-defer/long.js?sp
5 </body>

Pero esta solución está lejos de ser perfecta. Por ejemplo el navegador solo se dará cuenta del script (y
podrá empezar a descargarlo) después de descargar todo el documento HTML. Para documentos HTML
extensos eso puede ser un retraso notable.

Este tipo de cosas son imperceptibles para las personas que usan conexiones muy rápidas, pero muchas
personas en el mundo todavía tienen velocidades de internet lentas y utilizan una conexión de internet móvil
que esta lejos de ser perfecta.

Afortunadamente hay dos atributos de <script> que resuelven ese problema para nosotros: defer y
async .

defer
El atributo defer indica al navegador que no espere por el script. En lugar de ello, debe seguir procesando
el HTML, construir el DOM. El script carga “en segundo plano” y se ejecuta cuando el DOM esta completo.

Aquí está el mismo ejemplo de arriba, pero con defer :

 
1 <p>...contenido previo script...</p>
2
3 <script defer src="https://javascript.info/article/script-async-defer/long.j
4
5 <!-- Inmediatamete visible -->
6 <p>...contenido posterior al script...</p>

En otras palabras:

● Los scripts con defer nunca bloquean la página.


● Los scripts con defer siempre se ejecutan cuando el DOM esta listo (pero antes del evento
DOMContentLoaded ).

Los siguientes ejemplos demuestran la segunda parte:

 
1 <p>...contenido previo a los scripts...</p>
2
3 <script>
4 document.addEventListener('DOMContentLoaded', () => alert("¡DOM listo desp
5 </script>
6
7 <script defer src="https://javascript.info/article/script-async-defer/long.j
8
9 <p>...contenido posterior a los scripts...</p>

1. El contenido de la página se muestra inmediatamente.


2. DOMContentLoaded espera por el script diferido. Solo se dispara cuando el script es descargado y
ejecutado.

**Los scripts diferidos mantienen su orden relativo, tal cual los scripts regulares.

Digamos que tenemos dos scripts diferidos, long.js (largo) y luego small.js (corto):
1 <script defer src="https://javascript.info/article/script-async-defer/long.j
2 <script defer src="https://javascript.info/article/script-async-defer/small.

Los navegadores analizan la página en busca de scripts y los descarga en paralelo para mejorar el
rendimiento. Entonces en el ejemplo superior ambos scripts se descargan en paralelo, el small.js
probablemente lo haga primero.

…Pero el atributo defer , además de decirle al navegador “no bloquear”, asegura que el orden relativo se
mantenga. Entonces incluso si small.js se carga primero, aún espera y se ejecuta después de
long.js .

Por ello es importante para casos donde necesitamos cargar un librería JavaScript y entonces un script que
depende de ella.

 El atributo defer es solo para scripts externos


El atributo defer es ignorado si el <script> no tiene el atributo src .

async
El atributo async es de alguna manera como defer . También hace el script no bloqueante. Pero tiene
importantes diferencias de comportamiento.

El atributo async significa que el script es completamente independiente:

● El navegador no se bloquea con scripts async (como defer ).


● Otros scripts no esperan por scripts async , y scripts async no espera por ellos.
● DOMContentLoaded y los scripts asincrónicos no se esperan entre sí:
● DOMContentLoaded puede suceder antes que un script asincrónico (si un script asincrónico termina
de cargar una vez la página está completa)
● …o después de un script asincrónico (si tal script asincrónico es pequeño o está en cache)

En otras palabras, los scripts async cargan en segundo plano y se ejecutan cuando están listos. El DOM y
otros scripts no esperan por ellos, y ellos no esperan por nada. Un script totalmente independiente que se
ejecuta en cuanto se ha cargado. Tan simple como es posible, ¿cierto?

Aquí hay un ejemplo similar al que vimos con defer : Dos scripts long.js y small.js , pero ahora con
async en lugar de defer .

Los unos no esperan por lo otros. El que cargue primero (probablemente small.js ), se ejecuta primero.
 
1 <p>...contenido previo a los scripts...</p>
2
3 <script>
4 document.addEventListener('DOMContentLoaded', () => alert("¡DOM listo!"
5 </script>
6
7 <script async src="https://javascript.info/article/script-async-defer/long.j
8 <script async src="https://javascript.info/article/script-async-defer/small.
9
10 <p>...contenido posterior a los scripts...</p>

● El contenido de la página se muestra inmediatamente: async no lo bloquea.


● El evento DOMContentLoaded puede suceder antes o después de async , no hay garantías aquí.
● Un script más pequeño small.js que esté segundo probablemente cargue antes que uno más largo
long.js , entonces se ejecutará primero. Aunque podría ser que long.js cargue primero si está en
caché y ejecute primero. A eso lo llamamos “load-first order”, se ejecuta primero el que cargue antes .

Los scripts asincrónicos son excelentes cuando incluimos scripts de terceros (contadores, anuncios, etc) en
la página debido a que ellos no dependen de nuestros scripts y nuestros scripts no deberían esperar por
ellos.

1 <!-- Google Analytics is usually added like this -->


2 <script async src="https://google-analytics.com/analytics.js"></script

 El atributo async es solo para scripts externos


Tal como defer , el atributo async se ignora si la etiqueta <script> no tiene src .

Scripts dinámicos
Hay otra manera importante de agregar un script a la página.

Podemos crear un script y agregarlo dinámicamente al documento usando JavaScript:

 
1 let script = document.createElement('script');
2 script.src = "/article/script-async-defer/long.js";
3 document.body.append(script); // (*)

El script comienza a cargar tan pronto como es agregado al documento (*) .

Los scripts dinámicos se comportan como async por defecto

Esto es:

● Ellos no esperan a nadie y nadie espera por ellos.


● El script que carga primero se ejecuta primero ( load-first order )

Esto puede ser cambiado si explícitamente establecemos script.async=false . Así los scripts serán
ejecutados en el orden del documento, tal como en defer .

En este ejemplo, la función loadScript(src) añade un script y también establece async a false .

Entonces long.js siempre ejecuta primero (por haber sido agregado primero):

 
1 function loadScript(src) {
2 let script = document.createElement('script');
3 script.src = src;
4 script.async = false;
5 document.body.append(script);
6 }
7
8 // long.js se ejecuta primero a causa del async=false
9 loadScript("/article/script-async-defer/long.js");
10 loadScript("/article/script-async-defer/small.js");

Sin script.async=false , los scripts es ejecutarían de forma predeterminada, en el orden de carga


primero (probablemente small.js primero).

De nuevo, como con defer , el orden importa si queremos cargar una librería y luego otro script que
depende de ella.

Resumen
Ambos, async y defer , tienen algo en común: la descarga de tales scripts no bloquean el renderizado de
la página. Por lo cual el usuario puede leer el contenido de la página y familiarizarse con la página
inmediatamente.

Pero hay algunas diferencias esenciales entre ellos:

Orden DOMContentLoaded

Irrelevante. Puede cargar y ejecutarse mientras el documento no ha


Load-first order. El orden del
sido completamente descargado, eso puede pasar si el script es
async documento no importa. El que
pequeño o está en cache y el documento es suficientemente
carga primero ejecuta primero
extenso.

Document order (como van en Ejecutan después de que el documento es cargado y analizado
defer
el documento). (espera si es necesario), justo antes de DOMContentLoaded .

En la práctica, defer es usado para scripts que necesitan todo el DOM y/o si su orden de ejecución relativa
es importante.

Y async es usado para scripts independientes, como contadores y anuncios donde el orden de ejecución
no importa.
 La página sin scripts debe ser utilizable
Ten en cuenta: si usas defer o async , el usuario verá la página antes de que el script sea cargado.

En tal caso algunos componentes gráficos probablemente no estén listos.

No olvides poner alguna señal de “cargando” y deshabilitar los botones que aún no estén funcionando.
Esto permite al usuario ver claramente qué puede hacer en la página y qué está listo y qué no.

 Lección anterior Próxima lección



Compartir    Mapa del Tutorial

 Comentarios

● Si tiene sugerencias sobre qué mejorar, por favor enviar una propuesta de GitHub o una solicitud
de extracción en lugar de comentar.
● Si no puede entender algo en el artículo, por favor explique.
● Para insertar algunas palabras de código, use la etiqueta <code> , para varias líneas –
envolverlas en la etiqueta <pre> , para más de 10 líneas – utilice una entorno controlado
(sandbox) (plnkr, jsbin, codepen…)

© 2007—2024 Ilya Kantoracerca del proyecto


contáctenos

También podría gustarte