Laden von Drittanbieterskripts in Next.js optimieren

Hier erfahren Sie mehr über die Vision hinter der Script-Komponente von Next.js, die eine integrierte Lösung zur Optimierung des Ladens von Drittanbieter-Scripts bietet.

Leena Sohoni
Leena Sohoni

Etwa 45 % der Anfragen von Websites, die auf Mobilgeräten und Computern bereitgestellt werden, sind Drittanbieteranfragen, von denen 33 % Skripts sind. Die Größe, Latenz und das Laden von Drittanbieterskripts können die Leistung einer Website erheblich beeinträchtigen. Die Next.js-Script-Komponente enthält Best Practices und Standardeinstellungen, mit denen Entwickler Drittanbieterskripts in ihre Anwendungen einbinden und gleichzeitig potenzielle Leistungsprobleme beheben können.

Drittanbieterskripte und ihre Auswirkungen auf die Leistung

Drittanbieterskripts ermöglichen es Webentwicklern, vorhandene Lösungen zu nutzen, um gängige Funktionen zu implementieren und die Entwicklungszeit zu verkürzen. Die Ersteller dieser Skripts haben jedoch in der Regel keinen Anreiz, die Auswirkungen auf die Leistung der Website zu berücksichtigen, auf der sie verwendet werden. Diese Skripts sind auch für die Entwickler, die sie verwenden, eine Blackbox.

Skripts machen einen erheblichen Teil der Drittanbieter-Bytes aus, die von Websites in verschiedenen Kategorien von Drittanbieteranfragen heruntergeladen werden. Standardmäßig priorisiert der Browser Skripts basierend auf ihrer Position im Dokument. Dadurch kann sich die Erkennung oder Ausführung von Skripts verzögern, die für die Nutzerfreundlichkeit entscheidend sind.

Drittanbieterbibliotheken, die für das Layout erforderlich sind, sollten frühzeitig geladen werden, um die Seite zu rendern. Drittanbieter, die für das erste Rendering nicht erforderlich sind, sollten zurückgestellt werden, damit sie andere Verarbeitungen im Hauptthread nicht blockieren. Lighthouse bietet zwei Prüfungen, um Skripts zu kennzeichnen, die das Rendering oder den Hauptthread blockieren.

Lighthouse-Prüfungen für „Ressourcen entfernen, die das Rendering blockieren“ und „Drittanbieternutzung minimieren“

Es ist wichtig, die Reihenfolge des Ladens von Ressourcen auf Ihrer Seite zu berücksichtigen, damit kritische Ressourcen nicht verzögert und nicht durch unkritische Ressourcen blockiert werden.

Es gibt zwar Best Practices, um die Auswirkungen von Drittanbietern zu reduzieren, aber nicht jeder weiß, wie sie für jeden verwendeten Drittanbieter implementiert werden können. Das kann aus folgenden Gründen kompliziert sein:

  • Im Durchschnitt verwenden Websites 21 bis 23 verschiedene Drittanbieter – einschließlich Skripts – auf Mobilgeräten und Computern. Nutzung und Empfehlungen können jeweils variieren.
  • Die Implementierung vieler Drittanbieter kann sich je nach verwendetem Framework oder UI-Bibliothek unterscheiden.
  • Es werden häufig neue Bibliotheken von Drittanbietern eingeführt.
  • Unterschiedliche Geschäftsanforderungen im Zusammenhang mit demselben Drittanbieter erschweren es Entwicklern, die Nutzung zu standardisieren.

Auroras Fokus auf Drittanbieterskripte

Im Rahmen der Zusammenarbeit mit Open-Source-Web-Frameworks und ‑Tools stellt Aurora leistungsstarke Standardeinstellungen und spezialisierte Tools bereit, mit denen Entwickler Aspekte der Nutzerfreundlichkeit wie Leistung, Barrierefreiheit, Sicherheit und Mobilgerätefreundlichkeit verbessern können. 2021 haben wir uns darauf konzentriert, Framework-Stacks dabei zu unterstützen, die Nutzerfreundlichkeit und die Core Web Vitals-Messwerte zu verbessern.

Einer der wichtigsten Schritte zur Verbesserung der Framework-Leistung war die Erforschung der idealen Ladereihenfolge von Drittanbieterskripten in Next.js. Frameworks wie Next.js sind besonders gut geeignet, um nützliche Standardeinstellungen und Funktionen bereitzustellen, mit denen Entwickler Ressourcen, einschließlich Drittanbieterressourcen, effizient laden können. Wir haben umfangreiche HTTP Archive- und Lighthouse-Daten analysiert, um herauszufinden, welche Drittanbieter das Rendering in verschiedenen Frameworks am meisten blockieren.

Um das Problem zu beheben, dass Drittanbieterscripts, die in einer Anwendung verwendet werden, den Hauptthread blockieren, haben wir die Script-Komponente entwickelt. Die Komponente kapselt Sequenzierungsfunktionen, um Entwicklern bessere Steuerelemente für das Laden von Drittanbieterskripts zu bieten.

Drittanbieter-Skripts ohne Framework-Komponente sequenzieren

In der verfügbaren Anleitung zur Reduzierung der Auswirkungen von renderblockierenden Skripts werden die folgenden Methoden zum effizienten Laden und Sequenzieren von Drittanbieterskripts beschrieben:

  1. Verwenden Sie das Attribut async oder defer mit <script>-Tags, um den Browser anzuweisen, unkritische Drittanbieter-Skripts zu laden, ohne den Dokumentparser zu blockieren. Skripts, die für den ersten Seitenaufbau oder die erste Nutzerinteraktion nicht erforderlich sind, können als unkritisch eingestuft werden.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Stellen Sie frühzeitig Verbindungen zu erforderlichen Ursprüngen her, indem Sie „preconnect“ und „dns-prefetch“ verwenden. So können wichtige Skripts früher heruntergeladen werden.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. Verwenden Sie Lazy Loading für Ressourcen und eingebettete Inhalte von Drittanbietern, nachdem der Hauptinhalt der Seite geladen wurde oder wenn der Nutzer zu dem Teil der Seite scrollt, in dem sie enthalten sind.

Die Next.js-Script-Komponente

Die Next.js-Script-Komponente implementiert die oben genannten Methoden zur Sequenzierung von Skripts und bietet Entwicklern eine Vorlage, mit der sie ihre Ladestrategie definieren können. Sobald die geeignete Strategie festgelegt ist, wird sie optimal geladen, ohne andere wichtige Ressourcen zu blockieren.

Die Script-Komponente basiert auf dem HTML-Tag <script> und bietet die Möglichkeit, die Ladepriorität für Drittanbieter-Scripts mit dem Attribut „strategy“ festzulegen.

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

Das Attribut „strategy“ kann drei Werte annehmen.

  1. beforeInteractive: Diese Option kann für kritische Skripts verwendet werden, die ausgeführt werden sollen, bevor die Seite interaktiv wird. Next.js sorgt dafür, dass solche Skripts auf dem Server in das anfängliche HTML eingefügt und vor anderen selbst gebündelten JavaScript-Inhalten ausgeführt werden. Einwilligungsverwaltung, Bot-Erkennungsskripts oder Hilfsbibliotheken, die zum Rendern wichtiger Inhalte erforderlich sind, sind gute Kandidaten für diese Strategie.

  2. afterInteractive: Dies ist die Standardstrategie, die angewendet wird. Sie entspricht dem Laden eines Skripts mit dem Attribut „defer“. Es sollte für Skripts verwendet werden, die der Browser ausführen kann, nachdem die Seite interaktiv ist, z. B. Analysescripts. Next.js fügt diese Skripts clientseitig ein und sie werden ausgeführt, nachdem die Seite hydriert wurde. Sofern nicht anders angegeben, werden alle Drittanbieter-Scripts, die mit der Script-Komponente definiert wurden, von Next.js verzögert. Das ist eine gute Standardeinstellung.

  3. lazyOnload: Mit dieser Option können Skripts mit niedriger Priorität verzögert geladen werden, wenn der Browser inaktiv ist. Die von solchen Scripts bereitgestellten Funktionen sind nicht sofort erforderlich, nachdem die Seite interaktiv geworden ist, z. B. Chat- oder Social-Media-Plug-ins.

Entwickler können Next.js mitteilen, wie ihre Anwendung ein Skript verwendet, indem sie die Strategie angeben. So kann das Framework Optimierungen und Best Practices anwenden, um das Script zu laden und gleichzeitig die beste Ladereihenfolge zu gewährleisten.

Mit der Script-Komponente können Entwickler ein Drittanbieter-Script an einer beliebigen Stelle in der Anwendung für Drittanbieter mit verzögertem Laden und auf Dokumentebene für kritische Scripts platzieren. Das bedeutet, dass die Script-Komponente zusammen mit der Komponente, die das Script verwendet, platziert werden kann. Nach der Hydratation wird das Skript je nach verwendeter Strategie in den Kopf des ursprünglich gerenderten Dokuments oder am Ende des Textes eingefügt.

Wirkung messen

Wir haben die Vorlagen für die Next.js-Commerce-App und den Starter-Blog verwendet, um zwei Demo-Apps zu erstellen, mit denen wir die Auswirkungen der Einbindung von Drittanbieter-Skripts messen konnten. Häufig verwendete Drittanbieter für Google Tag Manager und Social-Media-Einbettungen wurden zuerst direkt auf den Seiten dieser Apps und dann über die Script-Komponente eingebunden. Anschließend haben wir die Leistung dieser Seiten mit WebPageTest verglichen.

Drittanbieterskripte in einer Next.js-E-Commerce-Anwendung

Der Vorlage für die Commerce-App wurden für die Demo die folgenden Drittanbieterskripts hinzugefügt.

Vorher Nach
Google Tag Manager mit async Skriptkomponente mit strategy = afterInteractive für beide Skripts
Twitter-Schaltfläche „Folgen“ ohne async oder defer
Konfiguration von Skript und Skriptkomponente für Demo 1 mit 2 Skripts.

Der folgende Vergleich zeigt den visuellen Fortschritt für beide Versionen des Next.js Commerce Starter-Kits. Wie Sie sehen, tritt der LCP fast 1 Sekunde früher auf, wenn die Script-Komponente mit der richtigen Ladestrategie aktiviert ist.

Filmstreifenvergleich, der die Verbesserung des LCP zeigt

Drittanbieterskripts in einem Next.js-Blog

Der Demo-Blog-App wurden Drittanbieterskripts hinzugefügt, wie unten dargestellt.

Vorher Nach
Google Tag Manager mit async Skriptkomponente mit strategy = lazyonload für jedes der vier Skripts
Twitter-Schaltfläche „Folgen“ mit asynchronem Code
YouTube-Abonnieren-Schaltfläche ohne async oder defer
LinkedIn-Schaltfläche „Folgen“ ohne „async“ oder „defer“
Konfiguration von Skript und Skriptkomponente für Demo 2 mit 4 Skripts.
Video, das den Ladefortschritt für die Indexseite mit und ohne Script-Komponente zeigt. Mit der Script-Komponente wird der FCP um 0,5 Sekunden verbessert.

Wie im Video zu sehen ist, tritt First Contentful Paint (FCP) auf der Seite ohne die Script-Komponente nach 0,9 Sekunden und mit der Script-Komponente nach 0,4 Sekunden auf.

Nächste Schritte für die Script-Komponente

Die Strategieoptionen für afterInteractive und lazyOnload bieten zwar eine erhebliche Kontrolle über Skripts, die das Rendering blockieren, wir prüfen jedoch auch andere Optionen, um die Nützlichkeit der Script-Komponente zu erhöhen.

Web-Worker verwenden

Web-Worker können verwendet werden, um unabhängige Skripts in Hintergrundthreads auszuführen. Dadurch wird der Hauptthread für die Verarbeitung von Aufgaben der Benutzeroberfläche freigegeben und die Leistung verbessert. Web-Worker eignen sich am besten, um die JavaScript-Verarbeitung und nicht die UI-Arbeit vom Hauptthread auszulagern. Skripts, die für den Kundensupport oder das Marketing verwendet werden und in der Regel nicht mit der Benutzeroberfläche interagieren, können gut in einem Hintergrundthread ausgeführt werden. Mit einer einfachen Drittanbieterbibliothek wie PartyTown können solche Skripts in einem Web-Worker isoliert werden.

Bei der aktuellen Implementierung der Next.js-Script-Komponente empfehlen wir, diese Scripts im Hauptthread zu verzögern, indem Sie die Strategie auf afterInteractive oder lazyOnload festlegen. In Zukunft möchten wir eine neue Strategieoption einführen, 'worker', mit der Next.js PartyTown oder eine benutzerdefinierte Lösung verwenden kann, um Skripts auf Web Workern auszuführen. Wir freuen uns über Kommentare von Entwicklern zu diesem RFC.

CLS minimieren

Eingebettete Inhalte von Drittanbietern wie Werbung, Videos oder Social-Media-Feeds können beim Lazy Loading zu Layoutverschiebungen führen. Das wirkt sich auf die Nutzerfreundlichkeit und den Messwert Cumulative Layout Shift (CLS) für die Seite aus. Der CLS kann minimiert werden, indem die Größe des Containers angegeben wird, in dem die Einbettung geladen wird.

Mit der Script-Komponente können Einbettungen geladen werden, die Layout Shifts verursachen können. Wir überlegen, sie um Konfigurationsoptionen zu erweitern, mit denen sich der CLS reduzieren lässt. Diese könnte in der Script-Komponente selbst oder als Begleitkomponente verfügbar gemacht werden.

Wrapper-Komponenten

Die Syntax und die Ladestrategie für die Einbindung gängiger Drittanbieter-Skripts wie Google Analytics oder Google Tag Manager (GTM) sind in der Regel festgelegt. Diese können für jeden Skripttyp in einzelne Wrapper-Komponenten gekapselt werden. Entwicklern steht nur eine minimale Anzahl anwendungsspezifischer Attribute (z. B. Tracking-ID) zur Verfügung. Wrapper-Komponenten helfen Entwicklern folgendermaßen:

  1. So können sie beliebte Script-Tags einfacher einbinden.
  2. Sicherstellen, dass das Framework im Hintergrund die optimale Strategie verwendet.

Fazit

Drittanbieterskripts werden in der Regel erstellt, um bestimmte Funktionen in die Website einzubinden, die sie verwendet. Um die Auswirkungen nicht kritischer Skripts zu reduzieren, empfehlen wir, sie zu verschieben. Dies geschieht standardmäßig durch die Next.js-Skriptkomponente. Entwickler können sich darauf verlassen, dass eingebundene Skripts wichtige Funktionen nicht verzögern, es sei denn, sie wenden explizit die Strategie beforeInteractive an. Wie bei der Next.js-Script-Komponente können Framework-Entwickler diese Funktionen auch in anderen Frameworks erstellen. Wir arbeiten aktiv daran, eine ähnliche Komponente mit dem Nuxt.js-Team zu entwickeln. Auf Grundlage des Feedbacks möchten wir die Script-Komponente weiter verbessern, um zusätzliche Anwendungsfälle abzudecken.

Danksagung

Vielen Dank an Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner und Addy Osmani für ihr Feedback zu diesem Beitrag.