
⏳ Chargement différé des scripts externes en JavaScript : guide complet 2026
Sept sites sur dix qui échouent à PageSpeed Insights ralentissent à cause de JavaScript tiers. Scripts externes, analytics, régies publicitaires, chats, polices, bandeaux cookies bloquent le rendu et repoussent le First Contentful Paint de plusieurs secondes. Et vous ne pouvez pas les désactiver: l’analytics alimente le marketing, le chat apporte des leads, sans bandeau cookies le site ne passe pas un audit.
Il existe une solution: le lazy loading. Le script ne se charge qu’une fois le contenu principal déjà affiché pour l’utilisateur. Le navigateur n’attend pas, les métriques Core Web Vitals passent au vert et les fonctionnalités du site n’en souffrent pas.
Nous avons rassemblé toutes les méthodes qui fonctionnent, des attributs HTML natifs aux techniques programmatiques en passant par les extensions WordPress. Avec des exemples de code que vous pouvez copier et appliquer dès aujourd’hui.
💡 Aperçu rapide:
- Comprendre
deferetasync: le tableau montre clairement la différence entre les attributs - Maîtriser le chargement programmatique sur l’événement
load: une version moderne de la méthode de Patrick Sexton - Configurer Intersection Observer pour les scripts sous la ligne de flottaison: chats, cartes, commentaires
- Optimiser WordPress sans toucher au code: les extensions Flying Scripts et Asset CleanUp
Comment les scripts tiers ralentissent le chargement
Le navigateur analyse le HTML de haut en bas. Lorsqu’il rencontre <script src="..."> sans attribut, l’analyse s’arrête: le navigateur charge le script, l’exécute, puis reprend seulement l’analyse de la page. C’est ce qu’on appelle le blocage du rendu.
Pour l’utilisateur, le résultat est un écran blanc. La métrique First Contentful Paint (FCP), c’est-à-dire le délai avant le premier affichage de contenu, dépend directement de la rapidité avec laquelle le navigateur a traité tous les scripts bloquants. Le FCP fait partie des Core Web Vitals et influence directement le classement dans les moteurs de recherche.
Les scripts tiers frappent plus fort que les vôtres: ils sont hébergés sur des serveurs externes et vous ne maîtrisez ni leur vitesse de diffusion ni leur disponibilité. Requête DNS, handshake TCP, handshake TLS, téléchargement, chaque étape ajoute des dizaines ou des centaines de millisecondes. Selon les données HTTP Archive pour 2024, le site médian sur mobile charge 21 scripts externes, dont trois sont bloquants.
La solution consiste à donner au navigateur une instruction claire: «charge le script en arrière-plan et exécute-le plus tard». C’est exactement à cela que servent les attributs defer et async.
Defer et async: deux mécanismes intégrés
Les deux attributs s’écrivent dans la balise <script> et modifient le comportement de chargement. De manière fondamentalement différente.
Attribut | Ordre de chargement | Moment d’exécution | Ordre d’exécution |
|---|---|---|---|
(aucun attribut) | Bloque l’analyse | Immédiatement après le chargement | Dans l’ordre du HTML |
| Parallèle à l’analyse | Immédiatement après le chargement | Le premier chargé |
| Parallèle à l’analyse | Après l’analyse complète du HTML | Dans l’ordre du HTML |
Defer: exécution différée avec garantie d’ordre
L’attribut defer indique au navigateur: «charge le script en arrière-plan, exécute-le après l’analyse complète du HTML». L’ordre d’exécution est préservé, les scripts s’exécutent exactement dans la séquence définie dans le balisage.
1 <script src="https://example.com/analytics.js" defer></script> 2 <script src="https://example.com/chat-widget.js" defer></script>
Le choix idéal pour les scripts qui doivent s’exécuter dans un ordre précis: la bibliothèque, puis son extension, puis l’initialisation. defer garantit que le DOM est prêt au moment de l’exécution. L’événement DOMContentLoaded se déclenche après tous les scripts defer.
Async: indépendance totale
async charge le script en parallèle de l’analyse et l’exécute immédiatement après le chargement, sans attendre les autres. L’ordre n’est pas garanti: le script arrivé le premier du serveur s’exécute le premier.
1 <script src="https://example.com/independent-widget.js" async></script>
Convient aux scripts totalement indépendants: compteurs de visites, boutons de réseaux sociaux, bannières publicitaires. Si le script ne dépend ni du DOM ni d’autres scripts, utilisez async.
Nuance importante: un script async peut s’exécuter avant que le DOM ne soit construit. S’il fait référence à des éléments de la page qui n’existent pas encore, vous obtiendrez null et une erreur dans la console. Vérifiez toujours.
Chargement programmatique sur l’événement load: la méthode de Patrick Sexton
Que faire si le script ne prend pas en charge defer/async ou si vous ne contrôlez pas le balisage? Par exemple, le script est inséré via Google Tag Manager ou codé en dur dans l’extension de quelqu’un d’autre. La méthode programmatique vient à la rescousse.
L’idée est simple: créer un élément <script> via JavaScript et l’ajouter au DOM seulement après le chargement complet de la page. L’auteur de cette approche, Patrick Sexton, a décrit la technique pour la première fois sur varvy.com.
La version moderne de ce code:
1 function loadScriptOnPageLoad(src) { 2 const script = document.createElement('script'); 3 script.src = src; 4 script.async = false; 5 document.body.appendChild(script); 6 } 7 8 window.addEventListener('load', () => { 9 loadScriptOnPageLoad('/wp-content/plugins/chat/chat.js'); 10 loadScriptOnPageLoad('/wp-content/plugins/analytics/tracker.js'); 11 });
Deux différences clés par rapport au code d’il y a dix ans. Premièrement: nous écoutons load, pas DOMContentLoaded. L’événement load se produit plus tard, lorsque toutes les images, styles et polices sont chargés. Un script différé est ainsi garanti de ne pas affecter le FCP ou le LCP. Deuxièmement: pas de window.attachEvent. Cette méthode n’était nécessaire que pour Internet Explorer 8 et versions antérieures, qui n’existent plus. La méthode moderne addEventListener fonctionne dans tous les navigateurs actuels.
Trois situations où l’approche programmatique est irremplaçable
defer et async ne fonctionnent que pour les balises <script> écrites directement dans le HTML. La méthode programmatique vous sauve lorsque:
- Le script est injecté via Google Tag Manager ou un autre gestionnaire de balises, vous ne voyez pas le balisage.
- Vous ne pouvez pas modifier le template: il s’agit d’un plugin ou d’un thème tiers avec une structure rigide.
- Vous avez besoin d’un chargement conditionnel: par exemple, un script de formulaire de contact uniquement sur les pages qui en contiennent un.
Intersection Observer: chargement à la demande
Pour certains scripts, même defer intervient trop tôt. Un widget de chat n’est pas nécessaire tant que l’utilisateur n’a pas fait défiler la page jusqu’au pied de page. Une carte, tant qu’il n’a pas atteint le bloc d’adresse. Des commentaires, tant qu’il n’a pas lu jusqu’à la section de discussion.
L’API Intersection Observer résout précisément ce problème: le script ne se charge que lorsque l’élément cible apparaît dans la fenêtre d’affichage.
1 const chatTarget = document.getElementById('chat-container'); 2 3 if (chatTarget) { 4 const observer = new IntersectionObserver((entries) => { 5 entries.forEach((entry) => { 6 if (entry.isIntersecting) { 7 const script = document.createElement('script'); 8 script.src = '/wp-content/plugins/chat/chat.js'; 9 document.body.appendChild(script); 10 observer.unobserve(entry.target); 11 } 12 }); 13 }, { rootMargin: '200px' }); 14 15 observer.observe(chatTarget); 16 }
Le paramètre rootMargin: '200px' charge le script 200 pixels avant que l’élément n’apparaisse à l’écran, l’utilisateur ne perçoit donc aucun délai. Auparavant, les développeurs ont utilisé pendant des années des écouteurs scroll avec getBoundingClientRect(), mais ceux-ci se déclenchaient à chaque pixel de défilement et surchargeaient le thread principal.
Intersection Observer fonctionne de manière asynchrone et n’impose quasiment aucune charge au navigateur. La prise en charge est assurée dans tous les navigateurs modernes, y compris Safari à partir de la version 12.1. IE11 n’est pas supporté, mais sa part de marché en juin 2026 tend vers l’erreur statistique.
WordPress: lazy loading sans toucher au code
Si le site est sous WordPress, vous pouvez mettre en place le lazy loading de trois manières, de la plus simple à la plus flexible.
Plugins pour le chargement différé des scripts
Deux options qui fonctionnent, testées sur des milliers de sites.
Flying Scripts, un plugin gratuit de Gijo Varghese, plus de 30 000 installations actives, version 1.2.4 (mise à jour en mai 2026). Il peut retarder l'exécution du JavaScript jusqu'à la première interaction de l'utilisateur: mouvement de souris, clic, défilement, toucher sur mobile. Vous spécifiez des mots-clés présents dans l'URL du script et le plugin en diffère l'exécution. Un délai d'expiration est prévu: si l'utilisateur n'interagit pas avec la page, les scripts s'exécutent après un temps défini. Gain maximal sur les métriques, mais le chat ou le formulaire de rappel doivent être exclus du délai, car ils sont nécessaires immédiatement.
WP Rocket, un plugin de cache premium avec une fonctionnalité intégrée de chargement différé du JavaScript. Il ajoute defer ou async aux scripts sélectionnés via l'interface d'administration. Vous spécifiez l'URL, le plugin modifie l'attribut lors du rendu de la page. Convient à ceux qui utilisent déjà WP Rocket pour la mise en cache et ne souhaitent pas multiplier les plugins.
Le hook script_loader_tag dans functions.php
Si vous ne voulez pas installer un plugin supplémentaire, WordPress permet de filtrer la sortie des balises <script> via le hook script_loader_tag. Le code ci-dessous ajoute defer à tous les scripts sauf jQuery et le panneau d'administration:
1 add_filter('script_loader_tag', function($tag, $handle) { 2 if (is_admin()) { 3 return $tag; 4 } 5 $skip = ['jquery', 'jquery-core', 'jquery-migrate']; 6 if (in_array($handle, $skip, true)) { 7 return $tag; 8 } 9 return str_replace(' src', ' defer src', $tag); 10 }, 10, 2);
Placez ce code dans le fichier functions.php du thème enfant ou via le plugin Code Snippets. Avant de l'appliquer, faites une sauvegarde. defer sur jQuery cassera tout code qui appelle $() ou jQuery() avant DOMContentLoaded. Commencez par des scripts individuels, vérifiez la console après chaque modification pour détecter d'éventuelles erreurs.
Contrôle total: Asset CleanUp
Asset CleanUp, un plugin gratuit (version 1.4.0.4, mise à jour en mai 2026) qui affiche TOUS les scripts et styles chargés sur une page, avec leur taille et leur source. Vous pouvez désactiver un script spécifique sur une page spécifique, changer l'attribut de chargement en defer/async, ou décharger complètement un asset inutile.
Le principal avantage par rapport à Flying Scripts: Asset CleanUp donne une vision complète pour chaque page. Vous voyez exactement ce qui se charge et prenez des décisions de manière précise. La version Pro ajoute le chargement conditionnel par type d'écran et le déplacement des scripts entre HEAD et BODY. Fonctionne avec n'importe quel plugin de cache, WP Rocket, W3 Total Cache, WP Fastest Cache.
Un approfondissement sur l'accélération de WordPress fait l'objet d'un article séparé: 21 conseils pour améliorer le score PageSpeed Insights. Si le problème ne vient pas seulement des scripts mais de la vitesse globale de l'hébergement, consultez les moyens de réduire le temps de chargement d'une page WordPress. Et les outils pour vérifier la performance de WordPress vous aideront à mesurer l'effet réel de l'optimisation.
Vidéo: async et defer en pratique
Une explication de cinq minutes par la chaîne xplodivity, avec des schémas visuels de chargement et des exemples de code en direct:
⁉️🤔 Foire aux questions
defer ou async, lequel choisir pour Google Analytics?**
async. Analytics.js et gtag.js sont totalement indépendants du DOM, ils n'ont pas besoin d'un ordre d'exécution. GA4 recommande officiellementasync, la bibliothèque gère elle-même l'initialisation différée.
Quelle est la différence entre l'événement load et DOMContentLoaded?
DOMContentLoadedse déclenche lorsque le HTML est entièrement analysé et l'arbre DOM construit, les styles et images peuvent encore être en cours de chargement.loadintervient plus tard: quand absolument tout est chargé, y compris les images, les polices et les feuilles de style. Pour le chargement différé de scripts,loadest plus sûr: à ce stade, la page a déjà été affichée à l'utilisateur.
Peut-on ajouter defer à un script inline?
Non. L'attribut
deferne fonctionne que pour les scripts externes avec un attributsrc. Un script inline (<script>code</script>) avecdefersera ignoré, le navigateur l'exécutera comme un script bloquant normal. Pour différer du code inline, enveloppez-le dans un écouteurDOMContentLoadedouload.
Est-il sûr de mettre defer sur tous les scripts d'un site WordPress?
jQuery avec
defercassera tout code appelant$()oujQuery()avantDOMContentLoaded. C'est exactement pour cette raison que jQuery est exclu du traitement dans l'extrait ci-dessus. Commencez par les scripts non critiques: chat, réseaux sociaux, publicités. Élargissez la liste progressivement, en vérifiant la console après chaque modification.
Intersection Observer ou defer, lequel est le meilleur?
Ils résolvent des problèmes différents.
deferest destiné aux scripts toujours nécessaires sur la page mais non critiques pour le premier rendu: analytics, tests A/B. Intersection Observer est pour les scripts liés à un bloc spécifique: carte, chat dans le pied de page, widget de commentaires. Règle simple: script dans la partie haute de la page,defer; script sous la ligne de flottaison, Intersection Observer.
Que faire si Flying Scripts a cassé une fonctionnalité?
Excluez le script problématique de la liste de délai dans les paramètres du plugin. Flying Scripts permet de spécifier des mots-clés pour l'inclusion, supprimez le mot-clé du script problématique et il se chargera normalement. Pour les éléments critiques comme les formulaires et les chats, c'est une étape obligatoire avant d'activer le délai.
Que mettre sur votre site: matrice de décision
Le choix se résume à un tableau de décision simple:
- Le script est écrit en HTML, vous contrôlez les balises,
defers'il dépend de l'ordre,asyncs'il est totalement indépendant. - Le script est inséré via GTM ou le plugin d'un tiers, les balises sont inaccessibles, chargement programmatique sur l'événement
load. - Le script est lié à un bloc sous la ligne de flottaison, Intersection Observer avec
rootMargin: '200px'. - WordPress, vous en avez besoin sans coder, Flying Scripts (gratuit, plus de 30 000 sites) ou Asset CleanUp pour un contrôle complet des assets.
Commencez par le plus simple: ouvrez PageSpeed Insights, trouvez les scripts externes bloquants et ajoutez-leur defer. Un seul attribut, et le FCP peut passer du rouge au vert. Et quand vous maîtriserez les attributs, consultez notre revue des outils de vérification de performance WordPress, cela vous aidera à mesurer l'effet réel.



