En 2021, l'équipe Chrome Aurora a lancé le composant Script pour améliorer les performances de chargement des scripts tiers dans Next.js. Depuis son lancement, nous avons étendu ses fonctionnalités pour faciliter et accélérer le chargement de ressources tierces pour les développeurs.
Cet article de blog présente les nouvelles fonctionnalités que nous avons publiées, en particulier la bibliothèque @next/third-parties, ainsi qu'un aperçu des futures initiatives de notre feuille de route.
Conséquences des scripts tiers sur les performances
41% de l'ensemble des requêtes tierces sur les sites Next.js sont des scripts. Contrairement aux autres types de contenu, le téléchargement et l'exécution des scripts peuvent prendre un temps considérable, ce qui peut bloquer le rendu et retarder l'interactivité de l'utilisateur. Les données du rapport sur l'expérience utilisateur Chrome (CrUX) montrent que les sites Next.js qui chargent plus de scripts tiers ont des taux de réussite inférieurs pour Interaction to Next Paint (INP) et Largest Contentful Paint (LCP).
La corrélation observée dans ce graphique n'implique pas de causalité. Toutefois, les tests locaux fournissent des preuves supplémentaires que les scripts tiers ont un impact significatif sur les performances des pages. Par exemple, le graphique ci-dessous compare différentes métriques de laboratoire lorsqu'un conteneur Google Tag Manager (comprenant 18 balises sélectionnées au hasard) est ajouté à Taxonomy, une application exemple populaire de Next.js.
La documentation WebPageTest explique en détail comment ces temps sont mesurés. D'un coup d'œil, il est clair que toutes ces métriques de laboratoire sont affectées par le conteneur GTM. Par exemple, le Total Blocking Time (TBT) (temps de blocage total), un proxy de laboratoire utile qui se rapproche de l'INP, a augmenté de près de 20 fois.
Composant "Script"
Lorsque nous avons publié le composant <Script>
dans Next.js, nous nous sommes assurés de l'introduire via une API conviviale qui ressemble étroitement à l'élément <script>
traditionnel. Grâce à elle, les développeurs peuvent colocaliser un script tiers dans n'importe quel composant de leur application, et Next.js se chargera de séquencer le script une fois les ressources critiques chargées.
<!-- By default, script will load after page becomes interactive -->
<Script src="https://example.com/sample.js" />
<!-- Script is injected server-side and fetched before any page hydration occurs -->
<Script strategy=”beforeInteractive” src="https://example.com/sample.js" />
<!-- Script is fetched later during browser idle time -->
<Script strategy=”lazyOnload” src="https://example.com/sample.js" />
Des dizaines de milliers d'applications Next.js, y compris des sites populaires tels que Patreon, Target et Notion, utilisent le composant <Script>
. Malgré son efficacité, certains développeurs ont exprimé des inquiétudes concernant les points suivants:
- Emplacement du composant
<Script>
dans une application Next.js, tout en respectant les différentes instructions d'installation des différents fournisseurs tiers (expérience pour les développeurs). - Quelle stratégie de chargement est la plus optimale à utiliser pour différents scripts tiers (expérience utilisateur) ?
Pour répondre à ces deux préoccupations, nous avons lancé @next/third-parties
, une bibliothèque spécialisée proposant un ensemble de composants et d'utilitaires optimisés adaptés aux tiers populaires.
Expérience pour les développeurs: gérer plus facilement les bibliothèques tierces
De nombreux scripts tiers sont utilisés par un pourcentage important de sites Next.js, Google Tag Manager étant le plus populaire, utilisé par 66% des sites.
@next/third-parties
s'appuie sur le composant <Script>
en introduisant des wrappers de niveau supérieur conçus pour simplifier l'utilisation de ces cas d'utilisation courants.
import { GoogleAnalytics } from "@next/third-parties/google";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
<GoogleTagManager gtmId="GTM-XYZ" />
</html>
);
}
Google Analytics, un autre script tiers largement utilisé (52% des sites Next.js), dispose également d'un composant dédié.
import { GoogleAnalytics } from "@next/third-parties/google";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
<GoogleAnalytics gaId="G-XYZ" />
</html>
);
}
@next/third-parties
simplifie le processus de chargement des scripts couramment utilisés, mais il étend également notre capacité à développer des utilitaires pour d'autres catégories tierces, telles que les implémentations. Par exemple, les intégrations Google Maps et YouTube sont utilisées dans respectivement 8% et 4% des sites Web Next.js. Nous avons également publié des composants pour les charger plus facilement.
import { GoogleMapsEmbed } from "@next/third-parties/google";
import { YouTubeEmbed } from "@next/third-parties/google";
export default function Page() {
return (
<>
<GoogleMapsEmbed
apiKey="XYZ"
height={200}
width="100%"
mode="place"
q="Brooklyn+Bridge,New+York,NY"
/>
<YouTubeEmbed videoid="ogfYd705cRs" height={400} params="controls=0" />
</>
);
}
Expérience utilisateur: accélérer le chargement des bibliothèques tierces
Dans un monde idéal, chaque bibliothèque tierce largement adoptée serait entièrement optimisée, rendant inutiles les abstractions qui améliorent ses performances. Toutefois, en attendant que cela devienne une réalité, nous pouvons essayer d'améliorer leur expérience utilisateur lorsqu'ils sont intégrés via des frameworks populaires tels que Next.js. Nous pouvons tester différentes techniques de chargement, nous assurer que les scripts sont séquencés correctement et, au final, partager nos commentaires avec les fournisseurs tiers pour encourager les modifications en amont.
Prenons l'exemple des vidéos YouTube intégrées. Certaines implémentations alternatives offrent de bien meilleures performances que l'intégration native. Actuellement, le composant <YouTubeEmbed>
exporté par @next/third-parties
utilise lite-youtube-embed, qui, lors d'une démonstration dans une comparaison "Hello, World" Next.js, se charge beaucoup plus rapidement.
De même, pour Google Maps, nous incluons loading="lazy"
comme attribut par défaut pour l'intégration afin de nous assurer que la carte ne se charge que lorsqu'elle se trouve à une certaine distance de la fenêtre d'affichage. Il peut sembler évident d'inclure cet attribut, en particulier étant donné que la documentation Google Maps l'inclut dans son exemple d'extrait de code, mais seuls 45% des sites Next.js qui intègrent Google Maps utilisent loading="lazy"
.
Exécuter des scripts tiers dans un nœud de travail Web
Une technique avancée que nous explorons dans @next/third-parties
consiste à faciliter le transfert des scripts tiers vers un web worker. Popularisée par des bibliothèques telles que Partytown, cette approche peut réduire considérablement l'impact des scripts tiers sur les performances des pages en les déplaçant entièrement du thread principal.
Le GIF animé suivant montre les variations des tâches longues et du temps de blocage du thread principal lors de l'application de différentes stratégies <Script>
à un conteneur GTM sur un site Next.js. Notez que, bien que le passage d'une option de stratégie à une autre ne retarde que le moment où ces scripts s'exécutent, les déplacer vers un worker Web élimine complètement leur temps sur le thread principal.
Dans cet exemple particulier, le transfert de l'exécution du conteneur GTM et de ses scripts de balise associés vers un nœud de calcul Web a réduit le TBT de 92%.
Il est à noter que, si elle n'est pas gérée avec soin, cette technique peut casser silencieusement de nombreux scripts tiers, ce qui rend le débogage difficile. Dans les mois à venir, nous vérifierons si les composants tiers proposés par @next/third-parties
fonctionnent correctement lorsqu'ils sont exécutés dans un worker Web. Si c'est le cas, nous nous efforcerons de fournir aux développeurs un moyen simple et facultatif d'utiliser cette technique.
Étapes suivantes
Au cours du développement de ce package, il est apparu clairement qu'il était nécessaire de centraliser les recommandations de chargement tiers afin que d'autres frameworks puissent également bénéficier des mêmes techniques sous-jacentes. Nous avons donc créé Third Party Capital, une bibliothèque qui utilise le format JSON pour décrire les techniques de chargement tierces, qui sert actuellement de base à @next/third-parties
.
Nous allons continuer à améliorer les composants fournis pour Next.js et à inclure des utilitaires similaires dans d'autres frameworks et plates-formes CMS populaires. Nous collaborons actuellement avec les responsables de Nuxt et prévoyons de publier des utilitaires tiers similaires adaptés à leur écosystème dans un avenir proche.
Si l'un des tiers que vous utilisez dans votre application Next.js est compatible avec @next/third-parties
, installez le package et testez-le. Nous aimerions connaître votre avis sur GitHub.