« Pourquoi le Lighthouse est vert sur l’hébergement mais rouge en production ? » C’est la question posée par l’équipe marketing après l’intégration d’un widget de capture de leads HubSpot sur une landing page fraîchement lancée. Le serveur était pourtant rapide, le thème léger, les images optimisées. Le coupable se trouvait ailleurs : dans une balise <script> insérée sans attribut async ni defer, en plein milieu du <head>.
Ce script, fourni tel quel par l’interface HubSpot pour intégrer un formulaire, charge une bibliothèque JavaScript hébergée sur les serveurs de HubSpot avant de continuer le rendu de la page. Tant que ce fichier n’est pas téléchargé et exécuté, le navigateur suspend l’analyse du reste du document.
Symptôme : un First Contentful Paint qui stagne
Le rapport Lighthouse affichait un score de performance correct sur la page d’accueil, mais chutait fortement sur la landing page contenant le formulaire HubSpot : First Contentful Paint à 3,1 secondes, alors que le reste du site restait sous la seconde. L’audit signalait explicitement une ressource bloquant le rendu, avec un poids de script de 340 Ko avant même l’exécution du formulaire lui-même.
Diagnostic : un script placé au mauvais endroit, sans attribut de chargement
En inspectant le code source, le script HubSpot apparaissait entre deux feuilles de style, copié-collé directement depuis le panneau d’intégration de l’outil marketing, sans aucune modification :
<script type="text/javascript" src="https://js.hs-scripts.com/00000000.js"></script>

Sans attribut async ou defer, le navigateur bloque le parsing du HTML restant, y compris les feuilles de style et les balises qui suivent, jusqu’à ce que ce script soit entièrement téléchargé et exécuté. Sur une connexion mobile moyenne, ce blocage suffisait à lui seul à expliquer près de deux secondes du délai constaté.
Correctif : différer le chargement sans casser le widget
La correction retenue consiste à ajouter l’attribut defer, qui permet au navigateur de continuer à analyser le document pendant le téléchargement du script, puis de l’exécuter une fois le HTML entièrement parsé :
<script defer src="https://js.hs-scripts.com/00000000.js"></script>
Le widget HubSpot continue de fonctionner normalement : le formulaire s’affiche dès que le script s’exécute, quelques centaines de millisecondes plus tard, sans que l’utilisateur ne perçoive de différence visible sur une page correctement construite avec un espace réservé pour le formulaire. Après ce changement, le First Contentful Paint est redescendu à 1,2 seconde.
Aller plus loin : charger le script seulement au scroll
Sur cette landing page, le formulaire se trouvait en bas de page, après plusieurs sections de contenu. Un second correctif a consisté à ne charger le script qu’au moment où l’utilisateur approche de cette section, via un IntersectionObserver :
const formSection = document.querySelector( '#hubspot-form' );
const observer = new IntersectionObserver( ( entries ) => {
if ( entries[0].isIntersecting ) {
const script = document.createElement( 'script' );
script.src = 'https://js.hs-scripts.com/00000000.js';
document.body.appendChild( script );
observer.disconnect();
}
}, { rootMargin: '200px' } );
observer.observe( formSection );
Cette approche retarde totalement le chargement du script tant que l’utilisateur n’a pas fait défiler la page jusqu’à la zone concernée, ce qui améliore encore le temps de chargement initial pour les visiteurs qui ne descendent jamais jusqu’au formulaire.
Prévention : une checklist avant d’intégrer un widget marketing
- Ne jamais coller un extrait fourni par un outil tiers sans vérifier la présence de
asyncoudefer. - Placer les scripts tiers avant la fermeture de
</body>plutôt que dans le<head>quand l’outil le permet. - Tester systématiquement avec Lighthouse en conditions mobiles avant mise en production.
Un widget marketing ne devrait jamais avoir le droit de bloquer le rendu d’une page qu’il ne fait qu’enrichir.
En résumé
Un simple attribut manquant sur une balise script peut coûter près de deux secondes de First Contentful Paint sur une landing page par ailleurs bien optimisée. Le réflexe à adopter systématiquement lors de l’intégration d’un widget marketing consiste à vérifier son mode de chargement, à le différer chaque fois que possible, et à ne le charger qu’au moment où l’utilisateur en a réellement besoin.