En remplacement de http://javascript.developpez.com/faq...positionScript , entrée à laquelle j'ai moi-même participé, je propose une réponse plus complète introduisant les attributs async et defer. J'ai repris les explications de ce post:
http://www.developpez.net/forums/d15...y/#post8371661

Voilà la proposition:

TL;DR: si vous ne devez retenir qu'une seule option à appliquer en toutes circonstances, mettre tous les <script> dans <head> avec l'attribut defer est le meilleur compromis à toutes les situations exposées ci-dessous.

Plus un script est déclaré haut dans le code HTML d'un document, plus tôt le navigateur lancera la requête pour le télécharger. En effet, le navigateur n'attend pas que tout le document soit chargé: le HTML est interprété progressivement à mesure qu'il est reçu par le navigateur. C'est la même chose pour les feuilles CSS et pour toute autre ressource de la page. Bien sûr, la différence est significative uniquement si on a de gros documents, des pages HTML de plusieurs centaines de Ko. Si on regarde comment le Web a évolué, le HTML est aujourd'hui généralement bien plus léger que le reste (gros frameworks JS, CSS à rallonge, images haute définition etc...). Autrement dit, cette question du positionnement des balises <script> n'est plus si importante que ça.

S'il faut quand même répondre à la question du positionnement optimal des balises <script>, voilà la théorie :

  1. 1ère règle: les ressources importantes, c'est-à-dire celles qu'on souhaite avoir avant même que le document n'ait fini d'être téléchargé, doivent être idéalement placées dans <head>. C'est pour cette raison que l'on met les feuilles de style en <head>, pour avoir le document "décoré" tout de suite et éviter que l'utilisateur ne voit la page sans styles jusqu'à ce que le chargement de la page soit fini.
  2. 2ème règle: exception à cette 1ère règle: un script étant susceptible de modifier le contenu de la page, il est nécessaire de bloquer l'interprétation de la page pendant le chargement et l'exécution des scripts ; placer les scripts dans le <head> réduit ainsi la vitesse d'affichage de la page. On doit ce comportement notamment à document.write qui peut venir modifier le document avant-même que celui ait fini d'être chargé. Précision importante, ce qui est bloqué est seulement l'interprétation du HTML, pas son téléchargement qui continue en tâche de fond. Tous les navigateurs modernes savent très bien gérer ça maintenant, donc le temps de chargement total de la page est quasiment inchangé. En revanche, le délai d'attente avant que l'utilisateur commence à voir un bout de contenu de page est lui plus long, car conditionné par le chargement et l'exécution des scripts en <head>.
  3. 3ème règle, contre-exception : les attributs async et defer apparus avec HTML5 sur la balise <script> permettent de mieux gérer ce comportement de blocage du parser HTML, et donc d'avoir les gains de la 1ère règle sans les pertes de la 2ème règle.


Voilà pour la théorie. Qu'est-ce que cela donne en pratique ?

  • si vous devez supporter des navigateurs non compatibles HTML5, avez des pages HTML assez grosses et que votre site ne repose pas sur JavaScript pour fonctionner, mettez vos scripts avant la fermeture du </body>
  • si vous devez supporter des navigateurs non compatibles HTML5, avez des scripts assez lourds et importants pour faire fonctionner le site, mettez vos scripts dans le <head>
  • si vous supportez uniquement les navigateurs compatibles HTML5, mettez tous vos scripts dans <head> et :
    • Si le script dépend ou est requis par d'autres scripts, ou s'il doit travailler sur le DOM une fois chargé, ajoutez l'attribut defer.
    • Si le script est indépendant et fonctionnera peu importe quand il est interprété, ajoutez l'attribut async. (exemple: monitoring, statistiques, pub...)


Dans le cas des scripts utilisant jQuery, la principale raison pour laquelle on met leurs balises <script> juste avant la fermeture du </body>, c'est que l'on est sûrs que le DOM ( le modèle document constitué par le HTML qui précède) a été interprété et on peut donc utiliser les sélecteurs jQuery sans problème. Mais ce n'est pas une obligation, on peut très bien mettre le script en <head> et utiliser $(document).ready (https://api.jquery.com/ready/) pour savoir quand le DOM est prêt.

Autres liens explicatifs :
https://developer.mozilla.org/fr/doc...Element/script
http://www.growingwiththeweb.com/201...ttributes.html
Votre avis ? Je sais que c'est un sujet à débat, et pas forcément un débat très intéressant. Mais pour être objectif il faut rentrer dans les détails.