1903 votes

Où dois-je mettre les balises <script> dans le balisage HTML ?

Lorsque vous incorporez du JavaScript dans un document HTML, quel est l'endroit approprié pour placer l'attribut <script> et JavaScript inclus ? Je crois me souvenir que vous n'êtes pas censé placer ces éléments dans le dossier de l'utilisateur. <head> mais en plaçant au début de la section <body> est également une mauvaise chose, car le JavaScript devra être analysé avant que la page ne soit complètement rendue (ou quelque chose comme ça). Cela semble laisser le fin de la <body> comme un endroit logique pour <script> tags.

Alors, où est le bon endroit pour mettre le <script> tags ?

(Cette question fait référence cette question dans lequel il a été suggéré que les appels de fonctions JavaScript soient déplacés de l'espace de travail de l'UE vers l'extérieur. <a> balises pour <script> balises. J'utilise spécifiquement jQuery, mais des réponses plus générales sont également appropriées).

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> ? .

2388voto

Bart Points 2015

Voici ce qui se passe lorsqu'un navigateur charge un site web avec une <script> sur elle :

  1. Récupérer la page HTML (par exemple index.html)
  2. Commencez à analyser le HTML
  3. L'analyseur syntaxique rencontre un <script> faisant référence à un fichier script externe.
  4. 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.
  5. Après un certain temps, le script est téléchargé et ensuite exécuté.
  6. 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

0 votes

En utilisant cette méthode, quelle serait la meilleure façon d'exécuter le javascript après le chargement de tous les fichiers js ? Actuellement, j'utilise l'événement onload à l'intérieur de la balise d'ouverture du corps.

0 votes

Quelqu'un a-t-il des idées sur cette approche ? feedthebot.com/pagespeed/defer-loading-javascript.html

0 votes

Je ne peux pas vraiment imaginer beaucoup de scénarios où le DOM n'est pas modifié par JavaScript. Quelqu'un peut-il donner un exemple de script qui utiliserait async ?

255voto

Cammel Points 1637

Juste avant la balise de fermeture du corps, comme indiqué sur la page

http://developer.yahoo.com/performance/rules.html#js_bottom

Placez les scripts en bas de page

Le problème causé par les scripts est qu'ils bloquent les téléchargements parallèles. La spécification HTTP/1.1 suggère que les navigateurs ne téléchargent pas plus de deux composants en parallèle par nom d'hôte. Si vous servez vos images à partir de plusieurs noms d'hôtes, vous pouvez obtenir que plus de deux téléchargements se produisent en parallèle. Cependant, pendant le téléchargement d'un script, le navigateur ne lancera aucun autre téléchargement, même sur des noms d'hôtes différents.

7 votes

Je suis d'accord avec le concept et son explication. Mais que se passe-t-il si l'utilisateur commence à jouer avec la page. Supposons que j'ai une liste déroulante AJAX qui commencera à se charger après que la page soit apparue à l'utilisateur, mais pendant le chargement, l'utilisateur clique dessus ! Et que se passe-t-il si un utilisateur "vraiment impatient" soumet le formulaire ?

9 votes

@Hermant Vieux commentaire mais vous pouvez faire l'affaire en désactivant les champs par défaut puis en les activant par JS lorsque le DOM est complètement chargé. C'est ce que Facebook semble faire aujourd'hui.

2 votes

Je viens de le tester avec chrome, pour vérifier si c'est toujours le même problème. C'est le cas. Vous pouvez vérifier les différences de temps de chargement des pages de vos navigateurs ici. stevesouders.com/cuzillion

42voto

orip Points 28225

Le conseil standard, promu par l'équipe de Yahoo ! Exceptional Performance, est de mettre le <script> à la fin du corps du document afin qu'elles ne bloquent pas le rendu de la page.

Mais il existe des approches plus récentes qui offrent de meilleures performances, comme le décrit le document suivant cette réponse sur le temps de chargement du fichier JavaScript de Google Analytics :

Il y a quelques grandes diapositives par Steve Souders (expert en performance côté client) à propos de :

  • Différentes techniques pour charger des fichiers JavaScript externes en parallèle
  • leur effet sur le temps de chargement et le rendu des pages
  • le type d'indicateurs "en cours" que le navigateur affiche (par exemple, "chargement" dans la barre d'état, curseur de souris en forme de sablier).

1 votes

Re "à la fin du corps du document" : Avant la balise de fin de corps ( </body> ), vraisemblablement ? Pouvez-vous être plus clair ? (Mais sans "Modifier :", "Mettre à jour :", ou autre - la réponse doit apparaître comme si elle avait été écrite aujourd'hui).

1 votes

(Il ne faut pas confondre Steve Souders avec Steve Saunders ou John Saunders .)

25voto

Andrew Hare Points 159332

Si vous utilisez JQuery, placez le javascript là où vous le trouvez le mieux et utilisez $(document).ready() pour s'assurer que les choses sont chargées correctement avant d'exécuter toute fonction.

En passant, j'aime que toutes mes balises script se trouvent dans le répertoire de l'utilisateur. <head> car cela semble être l'endroit le plus propre.

14 votes

Dans la tête...er ? <header> ?

9 votes

Notez que l'utilisation de $(document).ready() ne signifie pas que vous pouvez mettre votre JavaScript partout que vous aimez - vous devez toujours le mettre après le <script src=".../jquery.min.js"> où vous incluez jQuery, de sorte que $ existe.

2 votes

Il n'est pas optimal de placer les balises script dans la section <head> - cela retardera l'affichage de la partie visible de la page jusqu'à ce que les scripts soient chargés.

10voto

Allain Lalonde Points 28717

Le XHTML ne sera pas validé si le script se trouve ailleurs que dans l'élément head. il s'avère que ça peut être partout.

Vous pouvez différer l'exécution avec quelque chose comme jQuery, de sorte que l'endroit où il est placé n'a pas d'importance (à l'exception d'une petite baisse de performance pendant l'analyse syntaxique).

1 votes

Le XHTML sera validé avec les balises script dans le corps, à la fois strict et transitoire. En revanche, les balises de style ne peuvent se trouver que dans l'en-tête.

0 votes

Re "L'endroit où il est placé n'a pas d'importance : Mais pas pour que le résultat ne soit pas HTML bien formé ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X