Découvrez la vision derrière le composant Script de Next.js, qui fournit une solution intégrée pour optimiser le chargement des scripts tiers.
Environ 45 % des requêtes provenant de sites Web diffusés sur mobile et ordinateur sont des requêtes tierces, dont 33 % sont des scripts. La taille, la latence et le chargement des scripts tiers peuvent avoir un impact significatif sur les performances d'un site. Le composant Script de Next.js intègre des bonnes pratiques et des valeurs par défaut pour aider les développeurs à introduire des scripts tiers dans leurs applications tout en résolvant les problèmes de performances potentiels dès le départ.
Scripts tiers et leur impact sur les performances
Les scripts tiers permettent aux développeurs Web d'exploiter les solutions existantes pour implémenter des fonctionnalités courantes et réduire le temps de développement. Toutefois, les créateurs de ces scripts ne sont généralement pas incités à prendre en compte l'impact sur les performances du site Web consommateur. Ces scripts sont également une boîte noire pour les développeurs qui les utilisent.
Les scripts représentent un nombre important d'octets tiers téléchargés par les sites Web dans différentes catégories de requêtes tierces. Par défaut, le navigateur priorise les scripts en fonction de leur emplacement dans le document, ce qui peut retarder la découverte ou l'exécution de scripts essentiels à l'expérience utilisateur.
Les bibliothèques tierces requises pour la mise en page doivent être chargées rapidement pour afficher la page. Les tiers qui ne sont pas requis pour l'affichage initial doivent être différés afin de ne pas bloquer d'autres traitements sur le thread principal. Lighthouse propose deux audits pour signaler les scripts qui bloquent l'affichage ou le thread principal.
Il est important de prendre en compte la séquence de chargement des ressources de votre page afin que les ressources critiques ne soient pas retardées et que les ressources non critiques ne bloquent pas les ressources critiques.
Bien qu'il existe des bonnes pratiques pour réduire l'impact des tiers, tout le monde ne sait pas forcément comment les mettre en œuvre pour chaque tiers utilisé. Cela peut être compliqué pour les raisons suivantes :
- En moyenne, les sites Web utilisent 21 à 23 tiers différents (y compris des scripts) sur mobile et sur ordinateur. L'utilisation et les recommandations peuvent varier pour chacun d'eux.
- L'implémentation de nombreux tiers peut varier selon qu'un framework ou une bibliothèque d'UI spécifiques sont utilisés.
- De nouvelles bibliothèques tierces sont fréquemment introduites.
- Les exigences métier variables liées à un même tiers compliquent la standardisation de son utilisation par les développeurs.
L'accent mis par Aurora sur les scripts tiers
La collaboration d'Aurora avec les frameworks et outils Web Open Source consiste en partie à fournir des valeurs par défaut solides et des outils d'opinion pour aider les développeurs à améliorer certains aspects de l'expérience utilisateur, tels que les performances, l'accessibilité, la sécurité et la compatibilité mobile. En 2021, nous nous sommes concentrés sur l'amélioration de l'expérience utilisateur et des métriques Core Web Vitals pour les piles de frameworks.
L'une des étapes les plus importantes pour atteindre notre objectif d'amélioration des performances du framework a consisté à rechercher la séquence de chargement idéale des scripts tiers dans Next.js. Les frameworks tels que Next.js sont particulièrement bien placés pour fournir des valeurs par défaut et des fonctionnalités utiles qui aident les développeurs à charger efficacement les ressources, y compris les ressources tierces. Nous avons étudié de nombreuses données de HTTP Archive et de Lighthouse pour identifier les tiers qui bloquent le plus l'affichage dans différents frameworks.
Pour résoudre le problème des scripts tiers qui bloquent le thread principal dans une application, nous avons créé le composant Script. Le composant encapsule les fonctionnalités de séquençage pour offrir aux développeurs de meilleurs contrôles pour le chargement de scripts tiers.
Séquencer des scripts tiers sans composant de framework
Les conseils disponibles pour réduire l'impact des scripts bloquant l'affichage fournissent les méthodes suivantes pour charger et séquencer efficacement les scripts tiers :
Utilisez l'attribut
asyncoudeferavec des balises<script>qui indiquent au navigateur de charger les scripts tiers non critiques sans bloquer l'analyseur de document. Les scripts qui ne sont pas requis pour le chargement initial de la page ou la première interaction de l'utilisateur peuvent être considérés comme non critiques.<script src="https://example.com/script1.js" defer></script> <script src="https://example.com/script2.js" async></script>Établissez des connexions précoces aux origines requises à l'aide de preconnect et dns-prefetch. Cela permet de lancer le téléchargement des scripts critiques plus tôt.
<head> <link rel="preconnect" href="http://PreconnThis.com"> <link rel="dns-prefetch" href="http://PrefetchThis.com"> </head>Chargez de manière différée les ressources et les intégrations tierces une fois que le contenu de la page principale a fini de se charger ou lorsque l'utilisateur fait défiler la page jusqu'à la partie où elles sont incluses.
Le composant Script de Next.js
Le composant de script Next.js implémente les méthodes ci-dessus pour séquencer les scripts et fournit un modèle permettant aux développeurs de définir leur stratégie de chargement. Une fois la stratégie appropriée spécifiée, elle se chargera de manière optimale sans bloquer d'autres ressources critiques.
Le composant Script s'appuie sur la balise HTML <script> et permet de définir la priorité de chargement des scripts tiers à l'aide de l'attribut strategy.
// Example for beforeInteractive:
<Script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver" strategy="beforeInteractive" />
// Example for afterInteractive (default):
<Script src="https://example.com/samplescript.js" />
// Example for lazyonload:
<Script src="https://connect.facebook.net/en_US/sdk.js" strategy="lazyOnload" />
L'attribut strategy peut prendre trois valeurs.
beforeInteractive: cette option peut être utilisée pour les scripts critiques qui doivent s'exécuter avant que la page ne devienne interactive. Next.js s'assure que ces scripts sont injectés dans le code HTML initial sur le serveur et exécutés avant les autres scripts JavaScript intégrés. La gestion du consentement, les scripts de détection des bots ou les bibliothèques d'aide nécessaires pour afficher du contenu critique sont de bons candidats pour cette stratégie.afterInteractive: il s'agit de la stratégie par défaut appliquée. Elle équivaut à charger un script avec l'attribut "defer". Elle doit être utilisée pour les scripts que le navigateur peut exécuter une fois que la page est interactive, par exemple les scripts d'analyse. Next.js injecte ces scripts côté client, et ils s'exécutent une fois la page hydratée. Ainsi, sauf indication contraire, tous les scripts tiers définis à l'aide du composant Script sont différés par Next.js, ce qui fournit une valeur par défaut forte.lazyOnload: cette option peut être utilisée pour charger de manière différée les scripts de faible priorité lorsque le navigateur est inactif. La fonctionnalité fournie par ces scripts n'est pas requise immédiatement après que la page devient interactive (par exemple, les plug-ins de chat ou de réseaux sociaux).
Les développeurs peuvent indiquer à Next.js comment leur application utilise un script en spécifiant la stratégie. Cela permet au framework d'appliquer des optimisations et des bonnes pratiques pour charger le script tout en garantissant la meilleure séquence de chargement.
Le composant Script permet aux développeurs de placer un script tiers n'importe où dans l'application pour les tiers à chargement tardif, et au niveau du document pour les scripts critiques. Cela implique que le composant Script peut être colocalisé avec le composant qui utilise le script. Après l'hydratation, le script sera injecté dans l'en-tête du document initialement affiché ou en bas du corps, selon la stratégie utilisée.
Mesurer l'impact
Nous avons utilisé les modèles de l'application de commerce et du blog de démarrage Next.js pour créer deux applications de démonstration qui nous ont permis de mesurer l'impact de l'inclusion de scripts tiers. Les tiers couramment utilisés pour Google Tag Manager et les intégrations de réseaux sociaux ont d'abord été inclus directement sur les pages de ces applications, puis via le composant Script. Nous avons ensuite comparé les performances de ces pages sur WebPageTest.
Scripts tiers dans une application d'e-commerce Next.js
Des scripts tiers ont été ajoutés au modèle d'application de commerce pour la démonstration, comme indiqué ci-dessous.
La comparaison suivante montre la progression visuelle des deux versions du kit de démarrage Next.js pour le commerce. Comme vous pouvez le voir, le LCP se produit près d'une seconde plus tôt lorsque le composant Script est activé avec la bonne stratégie de chargement.
Scripts tiers dans un blog Next.js
Des scripts tiers ont été ajoutés à l'application de blog de démonstration, comme indiqué ci-dessous.
| Avant | Après |
|---|---|
| Google Tag Manager avec chargement asynchrone | Composant de script avec strategy = lazyonload pour chacun des quatre scripts |
| Bouton "Suivre" de Twitter avec chargement asynchrone | |
| Bouton "S'abonner" YouTube sans async ni defer | |
| Bouton "Suivre" de LinkedIn sans async ni defer |
Comme on le voit dans la vidéo, le First Contentful Paint (FCP) se produit à 0,9 seconde sur la page sans le composant Script et à 0,4 seconde avec le composant Script.
Prochaines étapes pour le composant Script
Bien que les options de stratégie pour afterInteractive et lazyOnload offrent un contrôle important sur les scripts bloquant l'affichage, nous explorons également d'autres options qui augmenteraient l'utilité du composant Script.
Utiliser des nœuds de calcul Web
Les Web workers peuvent être utilisés pour exécuter des scripts indépendants sur des threads d'arrière-plan, ce qui peut libérer le thread principal pour gérer les tâches de l'interface utilisateur et améliorer les performances. Les Web Workers sont plus adaptés pour décharger le traitement JavaScript du thread principal que pour les tâches liées à l'UI. Les scripts utilisés pour le service client ou le marketing, qui n'interagissent généralement pas avec l'UI, peuvent être de bons candidats pour une exécution sur un thread d'arrière-plan. Une bibliothèque tierce légère, PartyTown, peut être utilisée pour isoler ces scripts dans un Web Worker.
Avec l'implémentation actuelle du composant de script Next.js, nous vous recommandons de différer ces scripts sur le thread principal en définissant la stratégie sur afterInteractive ou lazyOnload. À l'avenir, nous prévoyons d'introduire une nouvelle option de stratégie, 'worker', qui permettra à Next.js d'utiliser PartyTown ou une solution personnalisée pour exécuter des scripts sur des Web Workers. Nous invitons les développeurs à nous faire part de leurs commentaires sur cette RFC.
Réduire le CLS
Les intégrations tierces telles que les annonces, les vidéos ou les flux de réseaux sociaux peuvent entraîner des décalages de mise en page lorsqu'elles sont chargées en différé. Cela affecte l'expérience utilisateur et la métrique CLS (Cumulative Layout Shift) de la page. Vous pouvez réduire le CLS en spécifiant la taille du conteneur dans lequel l'intégration sera chargée.
Le composant Script peut être utilisé pour charger des éléments intégrés susceptibles de provoquer des décalages de mise en page. Nous envisageons de l'améliorer pour fournir des options de configuration qui aideront à réduire le CLS. Il peut être disponible dans le composant Script lui-même ou en tant que composant associé.
Composants wrapper
La syntaxe et la stratégie de chargement pour inclure des scripts tiers populaires tels que Google Analytics ou Google Tag Manager (GTM) sont généralement fixes. Ceux-ci peuvent être encapsulés dans des composants wrapper individuels pour chaque type de script. Seul un ensemble minimal d'attributs spécifiques à l'application (comme l'ID de suivi) sera disponible pour les développeurs. Les composants wrapper aideront les développeurs de différentes manières :
- Il est ainsi plus facile d'inclure des tags de script populaires.
- S'assurer que le framework utilise la stratégie la plus optimale en arrière-plan.
Conclusion
Les scripts tiers sont généralement créés pour inclure des fonctionnalités spécifiques dans le site Web qui les utilise. Pour réduire l'impact des scripts non critiques, nous vous recommandons de les différer, ce que le composant Script de Next.js fait par défaut. Les développeurs ont l'assurance que les scripts inclus ne retarderont pas les fonctionnalités critiques, sauf s'ils appliquent explicitement la stratégie beforeInteractive. Comme pour le composant de script Next.js, les développeurs de frameworks peuvent également envisager de créer ces fonctionnalités dans d'autres frameworks. Nous étudions activement la possibilité d'intégrer un composant similaire avec l'équipe Nuxt.js. En fonction des commentaires, nous espérons également améliorer le composant Script pour couvrir d'autres cas d'utilisation.
Remerciements
Merci à Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner et Addy Osmani pour leurs commentaires sur cet article.