JavaScript dans le Head ou le Footer : comment cela affecte les Core Web Vitals
Pourquoi defer dans le head est la meilleure pratique moderne, et quand le placement en footer a encore du sens

La réponse courte : defer dans le head
Dernière vérification par Arjen Karel en mars 2026
Le conseil classique était de placer JavaScript dans le footer. Ce conseil est dépassé. Avec async et defer supportés dans tous les navigateurs, le meilleur emplacement pour la plupart des scripts est dans le <head> avec un attribut defer.
La raison tient au preload scanner : votre navigateur découvre immédiatement les scripts du head et commence à les télécharger en parallèle avec l'analyse du HTML. Les scripts du footer sont découverts plus tard, ce qui signifie un début de téléchargement retardé. Le résultat est le même comportement non bloquant, mais avec une découverte plus rapide des ressources.
Selon le Web Almanac 2025, 85 % des pages échouent encore à l'audit des ressources bloquant le rendu. C'est un nombre énorme. Pendant ce temps, le Total Blocking Time mobile a augmenté de 58 % d'une année sur l'autre pour atteindre une médiane de 1 916 ms. JavaScript devient plus lourd, pas plus léger. Optimiser le placement de vos scripts est l'une des choses les plus simples que vous puissiez faire pour améliorer votre First Contentful Paint et votre Largest Contentful Paint.
Comment fonctionne le preload scanner
Le preload scanner est un second analyseur HTML qui s'exécute en avance sur l'analyseur principal. Il parcourt rapidement le HTML brut et commence à récupérer les ressources critiques (images, CSS, JavaScript) avant que l'analyseur principal ne les atteigne. Le preload scanner récupère les ressources approximativement dans l'ordre où il les découvre.
C'est là que le placement des scripts compte. Un script dans le <head> est découvert presque immédiatement. Un script en bas du <body> est découvert plus tard, surtout sur les documents HTML volumineux. Ce délai peut vous coûter des centaines de millisecondes sur une connexion mobile.
Les scripts injectés dynamiquement (créés via JavaScript) sont totalement invisibles pour le preload scanner. Le scanner ne découvre que les ressources qui existent dans le balisage HTML renvoyé par le serveur. C'est pourquoi différer JavaScript via des attributs HTML est presque toujours préférable à l'injection de scripts par code.
JavaScript dans le head
Placer JavaScript dans le <head> de la page lui offre la découverte la plus précoce possible par le preload scanner.
Avantages
- Découverte précoce : Le preload scanner trouve les scripts du head avant tout contenu du body. Le téléchargement commence le plus tôt possible.
- Exécution plus rapide : Les scripts dans le head (avec
defer) s'exécutent avant les scripts découverts plus tard dans le document. Pour une comparaison détaillée, consultez defer vs async JavaScript et les Core Web Vitals. - Séparation du code : Garder les références de scripts dans le
<head>les sépare du balisage de contenu, rendant le HTML plus facile à maintenir.
Inconvénients
- Blocage du rendu (sans defer ou async) : Un simple
<script>dans le head bloque l'analyse HTML jusqu'à ce que le script soit téléchargé et exécuté. Cela détruit votre First Contentful Paint. Utilisez toujoursdeferouasyncsur les scripts externes dans le head pour éviter cela. - Concurrence de bande passante : Les scripts du head à haute priorité entrent en concurrence pour la bande passante avec votre CSS, vos polices et votre image LCP. Sur les connexions lentes, cela peut pousser votre Largest Contentful Paint au-delà du seuil de 2,5 secondes.
Quand utiliser le placement dans le head
Utilisez le <head> pour les scripts critiques à l'expérience de la page : votre menu, bandeau de cookies, slider ou tout script affectant ce que le visiteur voit au-dessus de la ligne de flottaison. Ajoutez defer (ou async si l'ordre d'exécution n'a pas d'importance) pour empêcher le blocage du rendu. Les bibliothèques de détection de fonctionnalités appartiennent également au head, car elles doivent s'exécuter avant que le body ne soit analysé.
JavaScript dans le footer
Placer JavaScript juste avant la balise fermante </body> était le conseil de performance standard pendant des années. L'idée : laisser le HTML s'afficher d'abord, télécharger les scripts après.
Avantages
- Non bloquant par défaut : Les scripts du footer ne bloquent pas le rendu initial car le HTML au-dessus d'eux a déjà été analysé.
- Moins de concurrence de bande passante : Au moment où le navigateur atteint les scripts du footer, votre CSS, vos polices et votre image LCP ont déjà commencé à se télécharger.
Inconvénients
- Découverte tardive : Le preload scanner trouve les scripts du footer plus tard que les scripts du head. Sur une grande page, cela signifie un début de téléchargement et une exécution plus tardifs.
- Modèle obsolète :
<script defer>dans le<head>offre le même comportement non bloquant avec une découverte plus précoce. Le placement en footer était la solution de contournement avant quedefern'ait un support universel dans les navigateurs. Cette époque est révolue.
Quand le placement en footer a encore du sens
Le placement en footer peut avoir du sens pour les scripts que vous ne voulez vraiment pas voir entrer en concurrence pour la bande passante lors du chargement initial de la page : analytics, outils de tests A/B ou widgets sociaux. Mais même pour ceux-ci, defer dans le head est généralement le meilleur choix grâce à la découverte plus précoce par le preload scanner.
Attributs de script modernes
Au-delà de async et defer, il y a deux attributs supplémentaires à connaître :
type="module" : Les scripts de type module sont différés par défaut. Vous n'avez pas besoin d'ajouter defer à un script module car il se comporte déjà ainsi. Ajouter async à un script module remplace le comportement defer par défaut et le fait s'exécuter dès que le téléchargement est terminé.
fetchpriority : Par défaut, les scripts async et defer obtiennent une priorité réseau basse. Ajouter fetchpriority="high" à un script async vous donne un téléchargement non bloquant à haute priorité. C'est la combinaison idéale pour les scripts critiques à l'expérience utilisateur mais qui ne doivent pas bloquer le rendu. Pour une vue complète, consultez le guide de priorisation des ressources et les niveaux de priorité JavaScript.
Une stratégie pratique de placement des scripts
Tous les scripts ne méritent pas le même traitement. J'utilise une approche à quatre niveaux :
- Scripts critiques pour le rendu : Scripts qui affectent la mise en page visible de la page (menu, slider, interface au-dessus de la ligne de flottaison). Placez-les dans le
<head>sansdefers'ils doivent s'exécuter avant le premier affichage. Gardez-les aussi petits que possible car ils bloquent le rendu et nuiront à vos Core Web Vitals. - Scripts importants : Scripts critiques pour la conversion ou l'interaction (formulaires, navigation, consentement aux cookies). Placez-les dans le
<head>avecdeferouasync. - Scripts normaux : Scripts qui n'affectent pas le premier rendu de la page (carrousels, modales, onglets). Placez-les dans le
<head>avecdefer. - Scripts accessoires : Scripts dont vous pourriez vous passer si nécessaire (analytics, widgets de chat, partage social). Chargez-les après que la page a fini de s'afficher, en utilisant l'événement
loadourequestIdleCallback. Consultez 16 méthodes pour différer JavaScript pour les techniques. Si vous avez beaucoup de JavaScript inutilisé dans cette catégorie, consultez comment réduire le JavaScript inutilisé.
Les événements DOMContentLoaded et load vous permettent de contrôler le moment de l'exécution indépendamment de l'emplacement du script dans le HTML. C'est utile pour s'assurer que votre code s'exécute au bon moment.
Exemples de code
Exemple 1 : JavaScript dans le head (bloquant le rendu)
<!DOCTYPE html>
<html>
<head>
<title>JavaScript in the Head Example</title>
<script>
function showMessage() {
alert("Hello from JavaScript in the head!");
}
</script>
<!-- This script blocks rendering -->
<script src="script.js"></script>
</head>
<body>
<button onclick="showMessage()">Click Me</button>
</body>
</html>
Dans cet exemple, script.js dans le <head> bloque le rendu. Le navigateur n'affichera pas le bouton tant que le script n'aura pas été téléchargé et exécuté. Ajoutez defer à la balise script pour corriger cela.
Exemple 2 : JavaScript dans le footer
<!DOCTYPE html>
<html>
<head>
<title>JavaScript in the Footer Example</title>
</head>
<body>
<button onclick="showMessage()">Click Me</button>
<!-- Script at the end of the body -->
<script src="script.js"></script>
<script>
function showMessage() {
alert("Hello from JavaScript in the footer!");
}
</script>
</body>
</html>
Ici, script.js se charge après le contenu HTML, il ne bloque donc pas le rendu. Mais le preload scanner le découvre plus tard que s'il était dans le head. Utiliser <script defer src="script.js"></script> dans le <head> vous donne le même comportement non bloquant avec une découverte de téléchargement plus précoce.
Exemple 3 : Utilisation des écouteurs d'événements
<!DOCTYPE html>
<html>
<head>
<title>Event Listener Example</title>
<script>
window.addEventListener('load', function() {
console.log("Page is fully loaded.");
});
</script>
</head>
<body>
<!-- Page content -->
</body>
</html>
L'écouteur d'événement load garantit que le code à l'intérieur du callback ne s'exécute qu'après le chargement complet de la page, indépendamment de l'emplacement du script. C'est utile pour l'initialisation non critique qui doit attendre que tout le reste soit prêt.
Vérifiez vos modifications
Après avoir déplacé les scripts du footer vers defer dans le <head>, vérifiez l'impact avec le Real User Monitoring. Votre FCP et votre LCP devraient tous deux s'améliorer. Sur les sites surveillés par CoreDash, les origines utilisant defer pour la majorité de leurs scripts ont un FCP médian 18 % plus rapide que les origines s'appuyant encore sur le placement en footer.
Find out what is actually slow.
I map your critical rendering path using real field data. You get a clear answer on what blocks LCP, what causes INP spikes, and where layout shifts originate.
Book a Deep Dive
