Laden von Drittanbieterskripts in Next.js optimieren

Lernen Sie die Idee hinter der Script-Komponente von Next.js kennen, einer integrierten Lösung zur Optimierung des Ladens von Drittanbieter-Scripts.

Leena Sohoni
Leena Sohoni

Etwa 45% der Anfragen von Websites, die über Mobilgeräte und Computer ausgeliefert werden, sind Drittanbieteranfragen, von denen 33% Scripts sind. Größe, Latenz und das Laden von Drittanbieterskripts können die Leistung einer Website erheblich beeinträchtigen. Die Next.js-Skriptkomponente verfügt über integrierte Best Practices und Standardeinstellungen, die Entwickler dabei unterstützen, Drittanbieter-Skripts in ihre Anwendungen zu integrieren und gleichzeitig potenzielle Leistungsprobleme zu beheben.

Drittanbieter-Skripts und ihre Auswirkungen auf die Leistung

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

Skripts machen eine große Anzahl von Drittanbieter-Byte aus, die von Websites für verschiedene Kategorien von Drittanbieteranfragen heruntergeladen wurden. Der Browser priorisiert Skripts standardmäßig nach ihrer Position im Dokument. Dadurch kann sich die Erkennung oder Ausführung von Skripts verzögern, die für die Nutzer wichtig sind.

Für das Layout erforderliche Bibliotheken von Drittanbietern sollten frühzeitig geladen werden, damit die Seite gerendert werden kann. Drittanbieter, die für das erste Rendering nicht benötigt werden, sollten aufgeschoben werden, damit sie keine andere Verarbeitung im Hauptthread blockieren. Lighthouse hat zwei Prüfungen, um Skripts zum Blockieren des Renderings oder des Hauptthreads zu kennzeichnen.

Lighthouse-Prüfungen für das Entfernen von Ressourcen, die das Rendering blockieren, und die Nutzung von Drittanbietern minimieren

Es ist wichtig, die Reihenfolge des Ladens Ihrer Seite zu berücksichtigen, damit kritische Ressourcen nicht verzögert werden und nicht kritische Ressourcen keine kritischen Ressourcen blockieren.

Es gibt zwar Best Practices, mit denen sich die Auswirkungen von Drittanbietern minimieren lassen, aber möglicherweise wissen nicht alle, wie sie für jeden Drittanbieter implementiert werden können. Das kann aus folgenden Gründen kompliziert sein:

  • Im Durchschnitt verwenden Websites für Mobilgeräte und Computer 21 bis 23 verschiedene Drittanbieter, einschließlich Skripts. Die Nutzung und Empfehlungen können sich je nach Anwendung unterscheiden.
  • Die Implementierung vieler Drittanbieter hängt davon ab, ob ein bestimmtes Framework oder eine Benutzeroberflächenbibliothek verwendet wird.
  • Neuere Bibliotheken von Drittanbietern werden häufig eingeführt.
  • Unterschiedliche Geschäftsanforderungen im Zusammenhang mit einem Drittanbieter erschweren es Entwicklern, die Verwendung zu standardisieren.

Aurora konzentriert sich auf Skripts von Drittanbietern

Ein Teil der Zusammenarbeit von Aurora mit Open-Source-Web-Frameworks und -Tools besteht darin, starke Standardeinstellungen und spezielle Tools bereitzustellen, mit denen Entwickler Aspekte der Nutzererfahrung wie Leistung, Barrierefreiheit, Sicherheit und Eignung für Mobilgeräte verbessern können. 2021 haben wir uns darauf konzentriert, Framework-Stacks dabei zu helfen, die Nutzerfreundlichkeit und die Core Web Vitals-Messwerte zu verbessern.

Einer der wichtigsten Schritte, um unser Ziel zur Verbesserung der Framework-Leistung zu erreichen, war die Untersuchung der idealen Ladesequenz von Drittanbieter-Skripts in Next.js. Frameworks wie Next.js eignen sich hervorragend für nützliche Standardeinstellungen und Funktionen, mit denen Entwickler Ressourcen, einschließlich Drittanbieter, effizient laden können. Wir haben umfangreiche Daten aus dem HTTP-Archiv und Lighthouse untersucht, um herauszufinden, welche Drittanbieter das Rendering in verschiedenen Frameworks am meisten blockieren.

Wir haben die Script-Komponente entwickelt, um den Hauptthread zu beheben, der Drittanbieter-Skripts in einer Anwendung blockiert. Die Komponente enthält Sequenzierungsfunktionen, um Entwicklern bessere Steuerungsmöglichkeiten für das Laden von Drittanbieter-Skripts zu bieten.

Sequenzierung von Drittanbieter-Skripts ohne Framework-Komponente

In der Anleitung zur Reduzierung der Auswirkungen von Skripts, die das Rendering blockieren, werden die folgenden Methoden zum effizienten Laden und Sequenzieren von Drittanbieterskripts beschrieben:

  1. Verwenden Sie das Attribut async oder defer mit <script>-Tags, die den Browser anweisen, nicht kritische Drittanbieterskripts zu laden, ohne den Dokumentparser zu blockieren. Skripts, die für den ersten Seitenaufbau oder die erste Nutzerinteraktion nicht erforderlich sind, sind möglicherweise nicht kritisch.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Stellen Sie frühe Verbindungen zu erforderlichen Ursprüngen mithilfe von preconnect und dns-prefetch her. 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. Lazy Loading von Ressourcen und Einbettungen von Drittanbietern, nachdem der Content der Hauptseite vollständig geladen wurde oder wenn der Nutzer nach unten zu dem Bereich der Seite scrollt, in dem sie enthalten sind

Next.js-Skriptkomponente

Die Next.js-Skriptkomponente implementiert die oben genannten Methoden für Sequenzierungsskripts und bietet eine Vorlage, mit der Entwickler ihre Ladestrategie definieren können. Sobald die geeignete Strategie festgelegt ist, wird sie optimal geladen, ohne andere kritische Ressourcen zu blockieren.

Die Skriptkomponente baut auf dem HTML-Tag <script> auf und bietet eine Option zum Festlegen der Ladepriorität für Skripts von Drittanbietern mithilfe des Attributs 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" />

Das Attribut „Strategie“ kann drei Werte annehmen.

  1. beforeInteractive: Diese Option kann für wichtige Skripts verwendet werden, die ausgeführt werden sollten, bevor die Seite interaktiv wird. Next.js stellt sicher, dass solche Skripts in den anfänglichen HTML-Code auf dem Server eingeschleust und vor anderem selbst gebündeltem JavaScript ausgeführt werden. Für diese Strategie eignen sich die Einwilligungsverwaltung, Skripts zur Bot-Erkennung oder Hilfsbibliotheken, die zum Rendern kritischer Inhalte erforderlich sind.

  2. afterInteractive: Das ist die angewendete Standardstrategie und entspricht dem Laden eines Skripts mit dem Attribut „Aussetzen“. Es sollte für Skripts verwendet werden, die der Browser ausführen kann, nachdem die Seite interaktiv ist, z. B. Analyseskripts. Next.js fügt diese Skripts clientseitig ein und sie werden ausgeführt, nachdem die Seite vollständig geladen wurde. Sofern nicht anders angegeben, werden daher alle Drittanbieterskripte, die mithilfe der Skriptkomponente definiert werden, von Next.js zurückgestellt, wodurch ein starker Standardwert bereitgestellt wird.

  3. lazyOnload: Mit dieser Option kann das Lazy Loading von Skripts mit niedriger Priorität verwendet werden, wenn der Browser inaktiv ist. Die durch solche Skripts 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 darüber informieren, wie ihre Anwendung ein Skript verwendet, indem sie die Strategie angeben. So kann das Framework Optimierungen und Best Practices zum Laden des Skripts anwenden und gleichzeitig die beste Ladesequenz sicherstellen.

Mit der Script-Komponente können Entwickler Drittanbieter-Skripts für spät geladene Drittanbieter an einer beliebigen Stelle in der Anwendung und für kritische Scripts auf Dokumentebene platzieren. Dies impliziert, dass sich die Skriptkomponente zusammen mit der Komponente befinden kann, die das Skript verwendet. Nach der Flüssigkeitszufuhr wird das Skript je nach verwendeter Strategie in den Kopf des ursprünglich gerenderten Dokuments oder in den unteren Teil des Textes injiziert.

Auswirkungen messen

Wir haben die Vorlagen für die Commerce-App und den Starter-Blog von Next.js verwendet, um zwei Demo-Apps zu erstellen, mit denen die Auswirkungen von Drittanbieterskripts gemessen werden konnten. Häufig verwendete Drittanbieter für Google Tag Manager und Einbettungen in sozialen Medien wurden zuerst direkt auf den Seiten dieser Apps eingefügt und dann über die Skriptkomponente. Anschließend haben wir die Leistung dieser Seiten auf WebPageTest verglichen.

Drittanbieter-Skripts in einer Next.js-Commerce-App

Der Vorlage für die E-Commerce-App für die Demo wurden wie unten dargestellt Drittanbieterskripts hinzugefügt.

Vorher Nachher
Google Tag Manager mit asynchronem Skript-Komponente mit Strategie = afterInteractive für beide Skripts
Twitter-Schaltfläche „Folgen“ ohne asynchron oder verzögert
Konfiguration der Script- und Script-Komponente für Demo 1 mit 2 Scripts.

Im folgenden Vergleich sehen Sie den visuellen Fortschritt beider Versionen des Next.js Commerce Starter-Kits. Wie Sie sehen, tritt der LCP fast eine Sekunde früher auf, wenn die Skriptkomponente mit der richtigen Ladestrategie aktiviert ist.

Vergleich von Filmstreifen mit Improvisation im LCP

Skripts von Drittanbietern in einem Next.js-Blog

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

Vorher Nachher
Google Tag Manager mit asynchronem Skript-Komponente mit Strategie = Lazyonload für jedes der vier Skripts
Twitter-Follow-Schaltfläche mit asynchronem
YouTube-Schaltfläche „Abonnieren“ ohne asynchrone oder verzögerte Auslieferung
LinkedIn Folgen-Schaltfläche ohne asynchron oder verzögert
Konfiguration von Script- und Script-Komponenten für Demo 2 mit 4 Scripts.
Video, das den Ladefortschritt für die Indexseite mit und ohne Skriptkomponente zeigt. Mit der Script-Komponente lässt sich der FCP-Wert um 0,5 Sekunden verbessern.

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

Nächste Schritte für die Skriptkomponente

Mit den Strategieoptionen für afterInteractive und lazyOnload haben Sie umfassende Kontrolle über Skripts, die das Rendering blockieren. Wir prüfen aber auch andere Optionen, die den Nutzen der Skriptkomponente steigern könnten.

Web-Worker verwenden

Web Worker können verwendet werden, um unabhängige Skripts in Hintergrundthreads auszuführen. Dadurch kann der Hauptthread freigegeben werden, um Verarbeitungsaufgaben für die Benutzeroberfläche zu erledigen und die Leistung zu verbessern. Web Worker eignen sich am besten, um die JavaScript-Verarbeitung statt UI-Aufgaben aus dem Hauptthread auszulagern. Für den Kundensupport oder das Marketing verwendete Skripts, die normalerweise nicht mit der Benutzeroberfläche interagieren, eignen sich gut für die Ausführung in einem Hintergrundthread. Sie können die einfache Drittanbieterbibliothek PartyTown verwenden, um solche Skripts in einen Web Worker zu isolieren.

Mit der aktuellen Implementierung der Next.js-Skriptkomponente empfehlen wir, diese Skripts im Hauptthread zurückzustellen, indem du die Strategie auf afterInteractive oder lazyOnload setzt. Wir empfehlen, demnächst eine neue Strategieoption namens 'worker' einzuführen. Damit kann Next.js PartyTown oder eine benutzerdefinierte Lösung verwenden, um Skripts auf Web Workern auszuführen. Wir freuen uns über Kommentare von Entwicklern zu diesem RFC.

CLS minimieren

Einbettungen von Drittanbietern wie Werbeanzeigen, Videos oder Feeds in sozialen Medien 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. CLS kann minimiert werden, indem die Größe des Containers angegeben wird, in den die Einbettung geladen wird.

Die Script-Komponente kann verwendet werden, um Einbettungen zu laden, die Layoutverschiebungen verursachen können. Wir erwägen eine Ergänzung, um Konfigurationsoptionen zur Verfügung zu stellen, mit denen die CLS reduziert wird. Diese kann innerhalb der Skript-Komponente selbst oder als Companion-Komponente zur Verfügung gestellt werden.

Wrapper-Komponenten

Die Syntax und die Ladestrategie für das Einbinden beliebter Drittanbieter-Skripts wie Google Analytics oder Google Tag Manager (GTM) sind in der Regel festgelegt. Diese können in einzelne Wrapper-Komponenten für jeden Skripttyp gekapselt werden. Entwicklern steht nur ein minimaler Satz anwendungsspezifischer Attribute (z. B. Tracking-ID) zur Verfügung. Wrapper-Komponenten bieten Entwicklern folgende Möglichkeiten:

  1. Das Einfügen beliebter Skript-Tags wird vereinfacht.
  2. Dafür sorgen, dass das Framework die optimale Strategie verwendet.

Fazit

Scripts von Drittanbietern werden in der Regel erstellt, um bestimmte Funktionen in die nutzende Website einzubinden. Um die Auswirkungen nicht kritischer Skripts zu verringern, sollten Sie sie aufschieben. Dies geschieht standardmäßig durch die Next.js-Skriptkomponente. Entwickler haben die Gewissheit, dass die eingefügten Scripts wichtige Funktionen nicht verzögern, es sei denn, sie wenden ausdrücklich die Strategie „beforeInteractive“ an. Wie bei der Next.js-Skriptkomponente können Framework-Entwickler diese Funktionen auch in anderen Frameworks erstellen. Wir arbeiten aktiv daran, mit dem Nuxt.js-Team eine ähnliche Komponente zu entwickeln. Aufgrund des Feedbacks hoffen wir, die Skriptkomponente weiter zu verbessern, um weitere 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.