Voici ce qui se passe lorsqu'un navigateur charge un site Web avec une <script>
balise dessus:
- Récupérer la page HTML (par exemple index.html)
- Commencez à analyser le code HTML
- L'analyseur rencontre une
<script>
balise référençant un fichier de script externe.
- Le navigateur demande le fichier de script. Pendant ce temps, l'analyseur bloque et arrête l'analyse de l'autre HTML sur votre page.
- Après un certain temps, le script est téléchargé puis exécuté.
- L'analyseur continue d'analyser le reste du document HTML.
L'étape # 4 provoque une mauvaise expérience utilisateur. Votre site Web s'arrête essentiellement de charger jusqu'à ce que vous ayez téléchargé tous les scripts. S'il y a une chose que les utilisateurs détestent, c'est d'attendre qu'un site Web se charge.
Pourquoi cela arrive-t-il même?
Tout script peut insérer son propre HTML via document.write()
ou d'autres manipulations DOM. Cela implique que l'analyseur doit attendre que le script ait été téléchargé et exécuté avant de pouvoir analyser en toute sécurité le reste du document. Après tout, le script pourrait pu insérer son propre code HTML dans le document.
Cependant, la plupart des développeurs JavaScript ne manipulent plus le DOM pendant le chargement du document. Au lieu de cela, ils attendent que le document soit chargé avant de le modifier. Par exemple:
<!-- 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";
});
Étant donné que votre navigateur ne sait pas que my-script.js ne va pas modifier le document tant qu'il n'a pas été téléchargé et exécuté, l'analyseur arrête l'analyse.
Recommandation désuète
L'ancienne approche pour résoudre ce problème était de mettre des <script>
balises au bas de votre<body>
, car cela garantit que l'analyseur n'est pas bloqué jusqu'à la fin.
Cette approche a son propre problème: le navigateur ne peut pas commencer à télécharger les scripts tant que le document entier n'est pas analysé. Pour les grands sites Web avec de grands scripts et feuilles de style, il est très important de pouvoir télécharger le script dès que possible pour les performances. Si votre site Web ne se charge pas dans les 2 secondes, les utilisateurs iront sur un autre site Web.
Dans une solution optimale, le navigateur commencerait à télécharger vos scripts dès que possible, tout en analysant le reste de votre document.
L'approche moderne
Aujourd'hui, les navigateurs prennent en charge le async
etdefer
attributs sur les scripts. Ces attributs indiquent au navigateur qu'il est sûr de continuer l'analyse pendant le téléchargement des scripts.
async
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
Les scripts avec l'attribut async sont exécutés de manière asynchrone. Cela signifie que le script est exécuté dès qu'il est téléchargé, sans bloquer le navigateur entre-temps.
Cela implique qu'il est possible de télécharger et d'exécuter le script 2 avant le script 1.
Selon http://caniuse.com/#feat=script-async , 97,78% de tous les navigateurs le soutiennent.
reporter
<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>
Les scripts avec l'attribut defer sont exécutés dans l'ordre (c'est-à-dire d'abord le script 1, puis le script 2). Cela ne bloque pas non plus le navigateur.
Contrairement aux scripts asynchrones, les scripts différés ne sont exécutés qu'après le chargement de l'intégralité du document.
Selon http://caniuse.com/#feat=script-defer , 97,79% de tous les navigateurs le soutiennent. 98,06% le soutiennent au moins partiellement.
Remarque importante sur la compatibilité du navigateur: dans certaines circonstances, IE <= 9 peut exécuter des scripts différés dans le désordre. Si vous devez prendre en charge ces navigateurs, veuillez d'abord lire ceci !
Conclusion
L'état actuel de la technique consiste à mettre des scripts dans la <head>
balise et à utiliser le async
oudefer
attributs . Cela permet de télécharger vos scripts dès que possible sans bloquer votre navigateur.
La bonne chose est que votre site Web devrait toujours se charger correctement sur les 2% de navigateurs qui ne prennent pas en charge ces attributs tout en accélérant les 98% restants.