Où dois-je mettre les balises dans le markup HTML?

lors de L'intégration de JavaScript dans un document HTML, où est l'endroit approprié pour mettre les étiquettes <script> et JavaScript inclus? Je crois me rappeler que vous n'êtes pas censé les placer dans la section <head> , mais le fait de les placer au début de la section <body> est mauvais, aussi, puisque le JavaScript devra être analysé avant que la page ne soit complètement rendue (ou quelque chose comme ça). Il semble que la section se termine par de la section <body> un endroit logique pour les étiquettes <script> .

alors, où est le bon endroit pour mettre les étiquettes <script> ?

(cette question fait référence à cette question , dans laquelle il a été suggéré que les appels de fonction JavaScript devraient être déplacés des étiquettes <a> aux étiquettes <script> . J'utilise spécifiquement jQuery, mais des réponses plus générales sont également appropriées.)

1197
demandé sur Community 2009-01-12 21:15:54
la source

20 ответов

voici ce qui se passe quand un navigateur charge un site Web avec une étiquette <script> dessus:

  1. Récupérer le code HTML de la page (par exemple index.html)
  2. Commencer l'analyse de la HTML
  3. L'analyseur rencontre un <script> tag référence à un fichier de script externe.
  4. le navigateur demande le fichier script. Pendant ce temps, l'analyseur bloque et cesse d'analyser L'autre HTML sur votre page.
  5. après un certain temps, le script est téléchargé et ensuite exécuté.
  6. l'analyseur continue à analyser le reste du document HTML.

L'Étape #4 provoque une mauvaise expérience utilisateur. Votre site web s'arrête 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?

N'importe quel script peut insérez 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 le reste du document en toute sécurité. Après tout, le script aurait pu avoir inséré son propre HTML dans le document.

cependant, la plupart des développeurs JavaScript ne manipulent plus le DOM alors que le document se charge. Au lieu de cela, ils attendent que le document a été chargé avant de le modifier. Par exemple:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script type="text/javascript" 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";
});

parce que votre navigateur ne connaît pas mon-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 <script> tags au fond de votre <body> , car cela permet de 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 jusqu'à ce que le document entier soit analysé. Pour les sites Web plus grands avec de grands scripts et feuilles de style, être en mesure de télécharger le script dès que possible est très important pour la performance. Si votre site web ne se charge pas dans les 2 secondes, les gens iront à un autre site web.

dans une solution optimale, le 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 les attributs async et defer sur les scripts. Ces attributs indiquent au navigateur qu'il est sûr de continuer à analyser pendant que les scripts sont téléchargés.

async

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

avec les Scripts async les attributs 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 dans le même 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 , 94,57% de tous les navigateurs supportent cette option.

"1519580920 de" reporter
<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

Scripts avec l'attribut defer sont exécutés dans l'ordre (i.e. premier script 1, puis script 2). Cela ne bloque pas non plus le navigateur.

Contrairement aux scripts async, les scripts defer ne sont exécutés qu'après le chargement du document entier.

selon http://caniuse.com/#feat=script-defer , 94.59% de tous les navigateurs le supportent. 94,92% l'appuient au moins partiellement.

une note importante sur le navigateur compatibilité: dans certaines circonstances, IE <= 9 peut exécuter des scripts différés hors ordre. Si vous avez besoin de prendre en charge ces navigateurs, s'il vous plaît lire ce d'abord!

Conclusion

l'état actuel de l'art est de mettre des scripts dans la balise <head> et d'utiliser les attributs async ou defer . Cela permet à vos scripts d'être téléchargés dès que possible sans bloquer votre navigateur.

la bonne chose est que votre site doit toujours charger correctement sur les 6% de navigateurs qui ne supportent pas ces attributs, tout en accélérant les autres 94%.

1508
répondu Bart 2018-07-22 22:29:48
la source

juste avant l'étiquette de fermeture, comme indiqué sur

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

Mettre les Scripts en Bas

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 de multiples les noms d'hôtes, vous pouvez obtenir plus de deux téléchargements en parallèle. Pendant qu'un script est en cours de téléchargement, cependant, le navigateur ne démarrera aucun autre téléchargement, même sur des noms d'hôtes différents.

219
répondu Cammel 2014-04-02 17:58:27
la source

les balises de script Non bloquantes peuvent être placées n'importe où:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async script sera exécuté de manière asynchrone dès qu'il sera disponible
  • defer script est exécuté lorsque le document a terminé l'analyse
  • async defer le script retombe dans le comportement defer si async n'est pas supporté

de tels scripts seront exécutés de manière asynchrone/après que le document soit prêt, ce qui signifie que vous ne pouvez pas faire cela:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

ou ceci:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

ou ceci:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

ou ceci:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

cela dit, les scripts asynchrones offrent ces avantages:

  • téléchargement parallèle de ressources :

    Le navigateur peut télécharger des feuilles de style, des images et d'Autres scripts en parallèle sans attendre qu'un script soit téléchargé et exécuté.
  • ordre de la Source de l'indépendance :

    Vous pouvez placer les scripts dans head ou body sans vous soucier de bloquer (utile si vous utilisez un CMS). L'ordre d'exécution toujours des questions.

il est possible de contourner les problèmes d'ordre d'exécution en utilisant des scripts externes qui prennent en charge les callbacks. De nombreux API JavaScript tiers prennent désormais en charge l'exécution sans blocage. Voici un exemple de chargeant asynchrone L'API GoogleMaps .

60
répondu Salman A 2015-02-06 16:37:32
la source

le conseil standard, promu par le Yahoo! Exceptional Performance team, est de mettre les tags <script> à la fin du corps du document afin qu'ils ne bloquent pas le rendu de la page.

mais il existe de nouvelles approches qui offrent de meilleures performances, comme décrit dans cette réponse à propos du temps de chargement du fichier JavaScript de Google Analytics:

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

  • Différentes techniques pour charger des fichiers JavaScript externes en parallèle
  • leur effet sur le temps de chargement et le rendu de la page
  • quels types d'indicateurs "en cours" le navigateur affiche (par exemple "chargement" dans la barre d'état, curseur de la souris hourglass).
36
répondu orip 2018-01-12 23:49:58
la source

si vous utilisez JQuery alors mettez le javascript où vous le trouvez le mieux et utilisez $(document).ready() pour s'assurer que les choses sont chargées correctement avant d'exécuter des fonctions.

sur une note latérale: j'aime toutes mes balises de script dans la section <head> car cela semble être l'endroit le plus propre.

20
répondu Andrew Hare 2014-04-02 18:05:52
la source

XHTML ne validera pas si le script est ailleurs qu'à l'intérieur de l'élément head. peut être partout.

vous pouvez reporter l'exécution avec quelque chose comme jQuery de sorte qu'il n'importe pas où il est placé (à l'exception d'une petite performance frappé pendant l'analyse).

9
répondu Allain Lalonde 2009-01-12 22:05:41
la source
<script src="myjs.js"></script>
</body>

script tag doit être utilisé toujours avant body close ou bas dans le fichier HTML .

ensuite, vous pouvez voir le contenu de la page avant de charger le fichier js .

cocher cette case si nécessaire : http://stevesouders.com/hpws/rule-js-bottom.php

8
répondu AmanKumar 2016-09-05 16:35:28
la source

la réponse conventionnelle (et largement acceptée) est" à la base", car alors le DOM entier aura été chargé avant que n'importe quoi puisse commencer l'exécution.

il y a des dissidents, pour diverses raisons, à commencer par la pratique disponible de commencer intentionnellement l'exécution avec un événement page onload.

5
répondu dkretz 2009-01-12 21:18:48
la source

en fonction du script et de son utilisation, le mieux possible (en termes de charge de page et de temps de rendu) peut être de ne pas utiliser une balise