Ein Next.js-Paket zum Verwalten von Bibliotheken von Drittanbietern

2021 führte das Chrome Aurora-Team die Script-Komponente ein, um die Ladeleistung von Drittanbieter-Scripts in Next.js zu verbessern. Seit der Einführung haben wir die Funktionen erweitert, um das Laden von Drittanbieterressourcen für Entwickler zu vereinfachen und zu beschleunigen.

In diesem Blogpost finden Sie eine Übersicht über die neueren Funktionen, die wir veröffentlicht haben, insbesondere die Bibliothek @next/third-parties, sowie einen Überblick über zukünftige Initiativen in unserer Roadmap.

Leistungsauswirkungen von Drittanbieter-Scripts

41% aller Anfragen von Drittanbietern auf Next.js-Websites sind Skripts. Im Gegensatz zu anderen Inhaltstypen kann das Herunterladen und Ausführen von Scripts ziemlich lange dauern. Das kann das Rendering blockieren und die Nutzerinteraktivität verzögern. Daten aus dem Bericht zur Nutzererfahrung in Chrome (Chrome User Experience, CrUX) zeigen, dass Next.js-Websites, auf denen mehr Drittanbieter-Scripts geladen werden, eine niedrigere Interaktion bis zur nächsten Darstellung (Interaction to Next Paint, INP) und eine niedrigere Abschlussrate für Largest Contentful Paint (LCP) haben.

Balkendiagramm, das den Rückgang des Prozentsatzes der Next.js-Seiten mit guten INP- und LCP-Werten im Verhältnis zur Anzahl der geladenen Drittanbieter zeigt
CrUX-Bericht vom Dezember 2023 (110.823 Websites)

Die in diesem Diagramm beobachtete Korrelation impliziert keine Kausalität. Lokale Tests liefern jedoch weitere Belege dafür, dass Drittanbieter-Scripts die Seitenleistung erheblich beeinträchtigen. Im folgenden Diagramm werden beispielsweise verschiedene Messwerte aus der Labs-Funktion verglichen, wenn der beliebten Next.js-Beispiel-App Taxonomy ein Google Tag Manager-Container mit 18 zufällig ausgewählten Tags hinzugefügt wird.

Balkendiagramm, das die Unterschiede bei verschiedenen Lab-Messwerten zeigt, wenn eine Website mit und ohne Google Tag Manager geladen wird
WebPageTest (Mobile 4G – Virginia, USA)

In der WebPageTest-Dokumentation finden Sie detaillierte Informationen dazu, wie diese Timings gemessen werden. Auf den ersten Blick ist klar, dass alle diese Messwerte vom GTM-Container betroffen sind. So konnte beispielsweise Total Blocking Time (TBT), ein nützlicher Lab-Proxy, der den INP-Wert annähert, eine Steigerung um das 20-Fache feststellen.

Script-Komponente

Bei der Einführung der <Script>-Komponente in Next.js haben wir darauf geachtet, sie über eine nutzerfreundliche API einzuführen, die dem traditionellen <script>-Element sehr ähnelt. So können Entwickler ein Drittanbieter-Script in jeder Komponente ihrer Anwendung platzieren. Next.js kümmert sich dann um die Sequenzierung des Scripts, nachdem wichtige Ressourcen geladen wurden.

<!-- 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" />

Die <Script>-Komponente wird in Zehntausenden von Next.js-Anwendungen verwendet, darunter beliebte Websites wie Patreon, Target und Notion. Trotz ihrer Effektivität haben einige Entwickler folgende Bedenken geäußert:

  • Platzierung der <Script>-Komponente in einer Next.js-App unter Einhaltung der unterschiedlichen Installationsanleitungen der verschiedenen Drittanbieter (Entwicklererfahrung)
  • Welche Ladestrategie ist für verschiedene Drittanbieter-Scripts am besten geeignet (Nutzerfreundlichkeit)?

Um diesen beiden Problemen entgegenzuwirken, haben wir @next/third-parties eingeführt – eine spezialisierte Bibliothek, die eine Reihe von optimierten Komponenten und Dienstprogrammen bietet, die auf beliebte Drittanbieter zugeschnitten sind.

Verwaltung von Drittanbieterbibliotheken für Entwickler

Viele Drittanbieter-Scripts werden auf einem erheblichen Prozentsatz der Next.js-Websites verwendet. Google Tag Manager ist dabei mit 66% am beliebtesten. @next/third-parties baut auf der <Script>-Komponente auf und führt übergeordnete Wrapper ein, die die Nutzung für diese gängigen Anwendungsfälle vereinfachen sollen.

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, ein weiteres gängiges Drittanbieterskript (52% der Next.js-Websites), verfügt ebenfalls über eine eigene Komponente.

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 vereinfacht das Laden häufig verwendeter Skripts und erleichtert außerdem die Entwicklung von Dienstprogrammen für andere Drittanbieterkategorien, z. B. Einbettungen. So werden Google Maps- und YouTube-Embeds beispielsweise auf 8% bzw. 4% der Next.js-Websites verwendet. Außerdem haben wir Komponenten eingeführt, die das Laden erleichtern.

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" />
    </>
  );
}

Nutzerfreundlichkeit: Bibliotheken von Drittanbietern werden schneller geladen

In einer perfekten Welt wäre jede weit verbreitete Drittanbieterbibliothek vollständig optimiert, sodass alle Abstraktionsschichten, die ihre Leistung verbessern, unnötig wären. Bis dahin können wir versuchen, die Nutzerfreundlichkeit zu verbessern, wenn sie über gängige Frameworks wie Next.js eingebunden werden. Wir können mit verschiedenen Ladetechniken experimentieren, dafür sorgen, dass Scripts richtig sequenziert werden, und unser Feedback an Drittanbieter weitergeben, um Änderungen an der Quelle anzuregen.

Nehmen wir z. B. YouTube-Embeds. Dabei haben einige alternative Implementierungen eine deutlich bessere Leistung als die native Einbettung. Derzeit verwendet die von @next/third-parties exportierte <YouTubeEmbed>-Komponente lite-youtube-embed, die bei einem Next.js-Vergleich mit „Hallo Welt“ deutlich schneller geladen wird.

GIF, das den Seitenladezeitvergleich zwischen der YouTube-Embed-Komponente und einem regulären YouTube-Iframe zeigt
WebPageTest (Mobile 4G – Virginia, USA)

Bei Google Maps wird loading="lazy" ebenfalls als Standardattribut für das Einbetten verwendet, damit die Karte nur geladen wird, wenn sie sich in einer bestimmten Entfernung vom Darstellungsbereich befindet. Das mag wie ein offensichtliches Attribut erscheinen, vor allem, da es in der Google Maps-Dokumentation im Beispiel-Code-Snippet enthalten ist. Aber nur 45% der Next.js-Websites, in die Google Maps eingebettet ist, verwenden loading="lazy".

Drittanbieterscripts in einem Webworker ausführen

Mit einer erweiterten Technik, die wir in @next/third-parties untersuchen, wird es einfacher, die Drittanbieter-Skripts an einen Web-Worker zu übertragen. Diese Methode, die durch Bibliotheken wie Partytown bekannt wurde, kann die Auswirkungen von Drittanbieter-Scripts auf die Seitenleistung erheblich reduzieren, da sie vollständig aus dem Hauptthread verschoben werden.

Das folgende animierte GIF zeigt die unterschiedlichen Längen von Aufgaben und der Blockierzeit des Hauptthreads, wenn verschiedene <Script>-Strategien auf einen GTM-Container auf einer Next.js-Website angewendet werden. Beachten Sie, dass beim Wechseln zwischen den Strategieoptionen nur der Zeitpunkt der Ausführung dieser Scripts verzögert wird. Wenn Sie sie jedoch in einen Webworker verschieben, werden sie nicht mehr im Haupt-Thread ausgeführt.

GIF, das Unterschiede bei der Blockierungszeit des Hauptthreads für die verschiedenen Script-Strategien zeigt
WebPageTest (Mobile 4G – Virginia, USA)

In diesem Beispiel wurde die Ausführung des GTM-Containers und der zugehörigen Tag-Scripts auf einen Webworker verlagert, wodurch sich die TBT um 92%reduzierte.

Hinweis: Wenn Sie diese Methode nicht sorgfältig handhaben, kann sie viele Drittanbieter-Scripts unbemerkt beeinträchtigen und die Fehlerbehebung erschweren. In den kommenden Monaten prüfen wir, ob Drittanbieterkomponenten, die von @next/third-parties angeboten werden, in einem Webworker richtig funktionieren. In diesem Fall werden wir daran arbeiten, Entwicklern eine einfache und optionale Möglichkeit zu bieten, diese Technik zu verwenden.

Nächste Schritte

Bei der Entwicklung dieses Pakets wurde klar, dass die Ladeempfehlungen von Drittanbietern zentralisiert werden müssen, damit auch andere Frameworks von denselben zugrunde liegenden Techniken profitieren können. Das hat uns dazu veranlasst, Third Party Capital zu entwickeln, eine Bibliothek, die mit JSON die Ladetechniken von Drittanbietern beschreibt und derzeit als Grundlage für @next/third-parties dient.

Als Nächstes werden wir uns weiterhin darauf konzentrieren, die für Next.js bereitgestellten Komponenten zu verbessern. Außerdem werden wir unsere Bemühungen ausweiten, ähnliche Dienstprogramme in andere gängige Frameworks und CMS-Plattformen aufzunehmen. Wir arbeiten derzeit mit Nuxt-Wartungspartnern zusammen und planen, in naher Zukunft ähnliche Drittanbieter-Dienstprogramme zu veröffentlichen, die auf deren System zugeschnitten sind.

Wenn einer der Drittanbieter, die Sie in Ihrer Next.js-App verwenden, von @next/third-parties unterstützt wird, installieren Sie das Paket und testen Sie es. Wir freuen uns über dein Feedback auf GitHub.