Esto es lo que sucede cuando un navegador carga un sitio web con una <script>
etiqueta:
- Obtener la página HTML (por ejemplo, index.html)
- Comience a analizar el HTML
- El analizador encuentra una
<script>
etiqueta que hace referencia a un archivo de script externo.
- El navegador solicita el archivo de script. Mientras tanto, el analizador bloquea y deja de analizar el otro HTML en su página.
- Después de un tiempo, el script se descarga y posteriormente se ejecuta.
- El analizador continúa analizando el resto del documento HTML.
El paso 4 causa una mala experiencia del usuario. Su sitio web básicamente deja de cargarse hasta que haya descargado todos los scripts. Si hay algo que los usuarios odian, está esperando que se cargue un sitio web.
¿Por qué sucede esto?
Cualquier script puede insertar su propio HTML a través de document.write()
u otras manipulaciones DOM. Esto implica que el analizador tiene que esperar hasta que la secuencia de comandos se haya descargado y ejecutado antes de poder analizar de forma segura el resto del documento. Después de todo, el script podría haber insertado su propio HTML en el documento.
Sin embargo, la mayoría de los desarrolladores de JavaScript ya no manipulan el DOM mientras se carga el documento. En cambio, esperan hasta que se haya cargado el documento antes de modificarlo. Por ejemplo:
<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>
Javascript:
// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});
Debido a que su navegador no sabe que my-script.js no va a modificar el documento hasta que se haya descargado y ejecutado, el analizador deja de analizarlo.
Recomendación anticuada
El viejo enfoque para resolver este problema era colocar <script>
etiquetas en la parte inferior de su <body>
, porque esto asegura que el analizador no esté bloqueado hasta el final.
Este enfoque tiene su propio problema: el navegador no puede comenzar a descargar los scripts hasta que se analice todo el documento. Para sitios web más grandes con grandes scripts y hojas de estilo, poder descargar el script lo antes posible es muy importante para el rendimiento. Si su sitio web no se carga en 2 segundos, las personas irán a otro sitio web.
En una solución óptima, el navegador comenzará a descargar sus scripts lo antes posible, mientras que al mismo tiempo analiza el resto de su documento.
El enfoque moderno
Hoy en día, los navegadores admiten los atributos async
y defer
en los scripts. Estos atributos le dicen al navegador que es seguro continuar analizando mientras se descargan los scripts.
asíncrono
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
Las secuencias de comandos con el atributo asincrónico se ejecutan de forma asincrónica. Esto significa que el script se ejecuta tan pronto como se descarga, sin bloquear el navegador mientras tanto.
Esto implica que es posible descargar y ejecutar el script 2 antes del script 1.
Según http://caniuse.com/#feat=script-async , el 97.78% de todos los navegadores lo admiten.
aplazar
<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>
Las secuencias de comandos con el atributo de aplazamiento se ejecutan en orden (es decir, primera secuencia de comandos 1, luego secuencia de comandos 2). Esto tampoco bloquea el navegador.
A diferencia de los scripts asíncronos, los scripts diferidos solo se ejecutan después de que se haya cargado todo el documento.
De acuerdo con http://caniuse.com/#feat=script-defer , el 97.79% de todos los navegadores lo admiten. El 98.06% lo respalda al menos parcialmente.
Una nota importante sobre la compatibilidad del navegador: en algunas circunstancias, IE <= 9 puede ejecutar scripts diferidos fuera de servicio. Si necesita soportar esos navegadores, ¡lea esto primero!
Conclusión
El estado actual de la técnica es colocar scripts en la <head>
etiqueta y usar los atributos async
o defer
. Esto permite que sus scripts se descarguen lo antes posible sin bloquear su navegador.
Lo bueno es que su sitio web aún debe cargarse correctamente en el 2% de los navegadores que no admiten estos atributos mientras acelera el otro 98%.