Voici ce qui se passe lorsqu'un navigateur charge un site web avec une <script>
sur elle :
- Récupérer la page HTML (par exemple index.html)
- Commencez à analyser le HTML
- L'analyseur syntaxique rencontre un
<script>
faisant référence à un fichier script externe.
- Le navigateur demande le fichier script. Pendant ce temps, l'analyseur syntaxique bloque et arrête d'analyser les autres éléments HTML de votre page.
- Après un certain temps, le script est téléchargé et ensuite exécuté.
- L'analyseur syntaxique continue à analyser le reste du document HTML.
L'étape n°4 entraîne une mauvaise expérience utilisateur. Votre site Web ne se charge pas tant que vous n'avez pas 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 est-ce que ça arrive ?
Tout script peut insérer son propre HTML par l'intermédiaire de 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 le reste du document en toute sécurité. Après tout, le script pourrait a inséré son propre HTML dans le document.
Cependant, la plupart des développeurs JavaScript ne manipulent plus le DOM tandis que le document est en train de se charger. 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";
});
Comme votre navigateur ne sait pas que mon-script.js ne va pas modifier le document avant d'avoir été téléchargé et exécuté, l'analyseur syntaxique arrête l'analyse.
Recommandation dépassée
L'ancienne approche pour résoudre ce problème consistait à mettre <script>
au bas de votre <body>
car cela permet de ne pas bloquer l'analyseur syntaxique jusqu'à la fin.
Cette approche a son propre problème : le navigateur ne peut pas commencer à télécharger les scripts avant que le document entier ne soit analysé. Pour les sites Web plus importants comportant des scripts et des feuilles de style volumineux, le fait de pouvoir télécharger le script dès que possible est très important pour les performances. Si votre site Web ne se charge pas en 2 secondes, les internautes iront sur un autre site.
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
et defer
sur les scripts. Ces attributs indiquent au navigateur qu'il est sûr de poursuivre l'analyse pendant que les scripts sont en cours de téléchargement.
asynchrone
<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>
Les scripts dotés de 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 que script 2 soit téléchargé et exécuté avant script 1.
Selon http://caniuse.com/#feat=script-async 97,78 % de tous les navigateurs le supportent.
différer
<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 script 1, puis 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'ensemble du document.
Selon http://caniuse.com/#feat=script-defer 97,79 % de tous les navigateurs le supportent. 98,06% le supportent au moins partiellement.
Une note importante sur la compatibilité des navigateurs : 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 lire le document suivant ce premier !
(Pour en savoir plus et voir des représentations visuelles très utiles des différences entre les scripts asynchrones, différés et normaux, consultez les deux premiers liens de la section Références de cette réponse).
Conclusion
L'état actuel de la technique consiste à placer les scripts dans le répertoire de l'utilisateur. <head>
et utiliser la balise async
ou defer
attributs. Cela permet à vos scripts d'être téléchargés dès que possible sans bloquer votre navigateur.
L'avantage est que votre site Web devrait continuer à se charger correctement sur les 2 % de navigateurs qui ne prennent pas en charge ces attributs, tout en accélérant les 98 % restants.
Références
1 votes
Si vous recherchez également une solution simple et que vous utilisez un générateur côté serveur comme Jekyll, je vous recommande d'inclure le script avec lui à la place. tellement plus simple !
3 votes
Si vous venez d'un moteur de recherche qui recherche ceci : De nombreuses réponses ne sont pas claires exactement à l'endroit où la balise script devrait se trouver à la fin. . Si la balise 'script' est après </body>", la validation HTML aboutira à _" Erreur : Balise de début erronée script. " (vérifier l'option "source" et cliquez sur "chèque"_ pour voir la source HTML). Il devrait être avant </body>'. (Le résultat est similaire si la balise 'script' se trouve à la toute fin, après la balise </html> tag.)
1 votes
Cette question est également abordée dans le document Est-il incorrect de placer la balise <script> après la balise </body> ? .