Package Next.js permettant de gérer les bibliothèques tierces

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 capacités pour faciliter et accélérer le chargement des ressources tierces pour les développeurs.

Cet article de blog présente les nouvelles fonctionnalités que nous avons lancées, en particulier la bibliothèque @next/third-parties, ainsi qu'un aperçu des futures initiatives de notre feuille de route.

Conséquences sur les performances des scripts tiers

41% des demandes tierces sur les sites Next.js sont des scripts. Contrairement à d'autres types de contenus, le téléchargement et l'exécution des scripts peuvent prendre beaucoup de temps, ce qui peut bloquer l'affichage et retarder l'interactivité de l'utilisateur. Les données du rapport d'expérience utilisateur Chrome (CrUX) montrent que les sites Next.js qui chargent plus de scripts tiers ont des taux de réussite Interaction to Next Paint (INP) et LCP (Largest Contentful Paint).

Graphique à barres montrant une baisse du pourcentage de Next.js atteignant des scores INP et LCP bons par rapport au nombre de tiers chargés
Rapport d'expérience utilisateur Chrome de décembre 2023 (110 823 sites)

La corrélation observée dans ce graphique n'implique pas de causalité. Toutefois, les tests en local fournissent des preuves supplémentaires que les scripts tiers ont un impact important sur les performances des pages. Par exemple, le graphique ci-dessous compare différentes métriques d'atelier lorsqu'un conteneur Google Tag Manager (composé de 18 balises sélectionnées au hasard) est ajouté à Taxonomy, un exemple d'application populaire pour Next.js.

Graphique à barres montrant les différences entre différentes métriques de l'atelier lorsqu'un site est chargé avec et sans Google Tag Manager
WebPageTest (Mobile 4G - Virginie États-Unis)

La documentation WebPageTest fournit des détails sur la manière dont ces délais sont mesurés. D'un coup d'œil, il apparaît clairement que toutes ces métriques d'atelier sont affectées par le conteneur Google Tag Manager. Par exemple, le Total Blocking Time (TBT), un proxy de laboratoire utile qui se rapproche de l'INP, a enregistré une augmentation de près de 20 fois.

Composant de script

Lorsque nous avons expédié le composant <Script> dans Next.js, nous avons veillé à l'introduire via une API conviviale qui ressemble beaucoup à l'élément <script> traditionnel. Grâce à lui, les développeurs peuvent colocaliser un script tiers dans n'importe quel composant de leur application, et Next.js se chargera de séquençage le script après le chargement des ressources critiques.

<!-- 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 sur les points suivants:

  • Où placer le composant <Script> dans une application Next.js tout en respectant les instructions d'installation différentes des différents fournisseurs tiers (expérience pour les développeurs).
  • Quelle stratégie de chargement est la plus optimale pour les 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 offrant un ensemble d'utilitaires et de composants optimisés adaptés aux applications tierces populaires.

Expérience pour les développeurs: faciliter la gestion des bibliothèques tierces

De nombreux scripts tiers sont utilisés sur une grande partie des sites Next.js. Google Tag Manager est le plus populaire (c'est le cas respectif de 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 couramment utilisé (52% des sites Next.js), possède également 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 intégrations. Par exemple, les intégrations Google Maps et YouTube sont utilisées respectivement sur 8% et 4% des sites Web Next.js. Nous avons également intégré des composants pour qu'ils soient plus faciles à charger.

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 parfait, chaque bibliothèque tierce largement adoptée serait entièrement optimisée, rendant inutiles les abstractions qui améliorent leurs performances. Toutefois, en attendant que cela devienne une réalité, nous pouvons essayer d'améliorer leur expérience utilisateur lorsqu'elles sont intégrées à l'aide de frameworks populaires tels que Next.js. Nous pouvons tester différentes techniques de chargement, nous assurer que les scripts sont séquencés de manière appropriée et, à terme, faire part de nos commentaires à des fournisseurs tiers pour encourager les modifications en amont.

Prenons l'exemple des intégrations YouTube. Certaines autres implémentations offrent de meilleures performances que l'intégration native. Actuellement, le composant <YouTubeEmbed> exporté par @next/third-parties utilise lite-youtube-embed qui, comme illustré dans la comparaison "Hello, World" de Next.js, se charge considérablement plus rapidement.

GIF montrant une comparaison du chargement de page entre le composant YouTube Embed et un iFrame YouTube standard
WebPageTest (Mobile 4G - Virginie États-Unis)

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. Cet attribut peut sembler évident, d'autant plus que la documentation de Google Maps l'inclut dans leur exemple d'extrait de code, mais seulement 45% des sites Next.js qui intègrent Google Maps utilisent loading="lazy".

Exécuter des scripts tiers dans un nœud de calcul Web

Une technique avancée que nous explorons dans @next/third-parties consiste à faciliter le déchargement des scripts tiers vers un nœud de calcul Web. Popularité 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 en dehors 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 dans un site Next.js. Notez que, bien que le basculement entre les options de stratégie ne fasse que retarder l'exécution de ces scripts, leur déplacement vers un nœud de calcul Web élimine complètement leur temps sur le thread principal.

GIF montrant les différences de temps de blocage du thread principal pour les différentes stratégies de script
WebPageTest (Mobile 4G - Virginie États-Unis)

Dans cet exemple particulier, le transfert de l'exécution du conteneur GTM et de ses scripts de balises associés vers un nœud de calcul Web a réduit la valeur de délai de mise à jour (TBT) de 92%.

Notez que si cette technique n'est pas gérée avec soin, elle peut interrompre silencieusement de nombreux scripts tiers, ce qui complique le débogage. 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 sur un nœud de calcul Web. Si tel est le cas, nous nous efforcerons de proposer aux développeurs un moyen simple et facultatif d'utiliser cette technique.

Étapes suivantes

Au cours du processus de développement de ce package, il est devenu évident 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 que celles utilisées. Cela nous a conduits à créer Third Party Capital, une bibliothèque qui utilise JSON pour décrire les techniques de chargement tierces, qui sert actuellement de base à @next/third-parties.

Au cours des prochaines étapes, nous continuerons à nous concentrer sur l'amélioration des composants fournis pour Next.js, et nous élargirons nos efforts pour inclure des utilitaires similaires dans d'autres frameworks et plates-formes CMS populaires. Nous travaillons actuellement en collaboration avec les responsables de Nuxt et prévoyons de lancer prochainement des utilitaires tiers similaires adaptés à leur écosystème.

Si l'un des tiers que vous utilisez dans votre application Next.js est compatible avec @next/third-parties, installez le package et lancez-vous ! Nous aimerions connaître votre avis sur GitHub.