Laden von Drittanbieterskripts in Next.js optimieren

Hier erfahren Sie mehr über die Script-Komponente von Next.js, die eine integrierte Lösung zum Optimieren des Ladens von Drittanbieter-Scripts bietet.

Leena Sohoni
Leena Sohoni

Etwa 45% der Anfragen von Websites, die auf Mobilgeräten und Computern ausgeliefert werden, sind Anfragen von Drittanbietern, von denen 33% Scripts sind. Größe, Latenz und Laden von Drittanbieter-Scripts können sich erheblich auf die Leistung einer Website auswirken. Die Next.js-Script-Komponente enthält integrierte Best Practices und Standardeinstellungen, die Entwicklern helfen, Drittanbieter-Scripts in ihre Anwendungen einzubinden und gleichzeitig potenzielle Leistungsprobleme zu beheben.

Drittanbieter-Scripts und ihre Auswirkungen auf die Leistung

Mit Drittanbieter-Scripts können Webentwickler vorhandene Lösungen nutzen, um gängige Funktionen zu implementieren und die Entwicklungszeit zu verkürzen. Die Ersteller dieser Scripts haben jedoch in der Regel keinen Anreiz, die Leistungsauswirkungen auf die Website zu berücksichtigen, auf der sie ausgeführt werden. Diese Scripts sind auch für die Entwickler, die sie verwenden, eine Blackbox.

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

Für das Layout erforderliche Drittanbieterbibliotheken sollten frühzeitig geladen werden, damit die Seite gerendert werden kann. Drittanbieter, die für das erste Rendering nicht erforderlich sind, sollten verschoben werden, damit sie keine anderen Verarbeitungen im Hauptthread blockieren. Lighthouse bietet zwei Prüfungen, mit denen Scripts gekennzeichnet werden, die das Rendern oder den Haupt-Thread blockieren.

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

Die Reihenfolge des Ressourcenladens Ihrer Seite ist wichtig, damit kritische Ressourcen nicht verzögert werden und nicht kritische Ressourcen keine kritischen Ressourcen blockieren.

Es gibt zwar Best Practices, um die Auswirkungen von Drittanbietern zu reduzieren, aber nicht jeder weiß, wie diese für alle verwendeten Drittanbieter implementiert werden. Das kann kompliziert sein, weil:

  • Im Durchschnitt nutzen Websites 21 bis 23 verschiedene Drittanbieter – einschließlich Scripts – auf Mobilgeräten und Computern. Die Verwendung und Empfehlungen können für jedes Gerät unterschiedlich sein.
  • Die Implementierung vieler Drittanbieter kann sich je nach verwendetem Framework oder UI-Bibliothek unterscheiden.
  • Neuere Bibliotheken von Drittanbietern werden häufig eingeführt.
  • Unterschiedliche geschäftliche Anforderungen im Zusammenhang mit demselben Drittanbieter erschweren es Entwicklern, die Verwendung zu standardisieren.

Aurora-Konzentration auf Drittanbieter-Scripts

Im Rahmen der Zusammenarbeit von Aurora mit Open-Source-Web-Frameworks und ‑Tools werden solide Standardeinstellungen und Tools zur Verfügung gestellt, mit denen Entwickler Aspekte der Nutzerfreundlichkeit wie Leistung, Barrierefreiheit, Sicherheit und Mobilität 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 zur Erreichung unseres Ziels, die Framework-Leistung zu verbessern, bestand darin, die ideale Ladesequenz von Drittanbieter-Scripts in Next.js zu ermitteln. Frameworks wie Next.js sind in der Lage, nützliche Standardeinstellungen und Funktionen bereitzustellen, mit denen Entwickler Ressourcen effizient laden können, einschließlich Drittanbieterressourcen. Wir haben umfangreiche HTTP Archive- und Lighthouse-Daten ausgewertet, um herauszufinden, welche Drittanbieter das Rendering in verschiedenen Frameworks am häufigsten blockieren.

Um das Problem zu beheben, dass Drittanbieter-Scripts, die in einer Anwendung verwendet werden, vom Haupt-Thread blockiert werden, haben wir die Script-Komponente entwickelt. Die Komponente umschließt Sequenzierungsfunktionen, um Entwicklern bessere Steuerelemente für das Laden von Drittanbieter-Scripts zur Verfügung zu stellen.

Drittanbieter-Scripts ohne Framework-Komponente sequenzieren

In der verfügbaren Anleitung zum Minimieren der Auswirkungen von renderblockierenden Scripts werden die folgenden Methoden zum effizienten Laden und Sequenzieren von Drittanbieter-Scripts beschrieben:

  1. Verwenden Sie das Attribut async oder defer mit <script>-Tags, die dem Browser mitteilen, nicht kritische Drittanbieter-Scripts zu laden, ohne den Dokumentparser zu blockieren. Scripts, die nicht für das erste Laden der Seite oder die erste Nutzerinteraktion erforderlich sind, können als nicht kritisch eingestuft werden.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Stellen Sie mithilfe von Preconnect und DNS-Prefetch frühzeitig Verbindungen zu erforderlichen Ursprüngen her. So kann der Download kritischer Scripts früher gestartet werden.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. Lazy-load Ressourcen und Einbettungen von Drittanbietern, nachdem der Inhalt der Hauptseite geladen wurde oder der Nutzer nach unten scrollt, bis er den Bereich der Seite erreicht, in dem sie enthalten sind.

Die Next.js-Script-Komponente

Die Next.js-Script-Komponente implementiert die oben genannten Methoden zur Sequenzierung von Scripts und bietet Entwicklern eine Vorlage, um ihre Ladestrategie zu definieren. Sobald die geeignete Strategie festgelegt wurde, wird sie optimal geladen, ohne andere kritische Ressourcen zu blockieren.

Die Script-Komponente basiert auf dem HTML-Tag <script> und bietet die Möglichkeit, die Ladepriorität für Drittanbieter-Scripts mithilfe des Attributs „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 Strategieattribut kann drei Werte annehmen.

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

  2. afterInteractive: Dies ist die Standardstrategie. Sie entspricht dem Laden eines Scripts mit dem Attribut „defer“. Sie sollte für Scripts verwendet werden, die der Browser ausführen kann, nachdem die Seite interaktiv geworden ist, z. B. Analysescripts. Next.js fügt diese Scripts clientseitig ein und sie werden ausgeführt, nachdem die Seite gehydratisiert wurde. Sofern nicht anders angegeben, werden alle Drittanbieter-Scripts, die mit der Script-Komponente definiert sind, von Next.js verschoben.

  3. lazyOnload: Mit dieser Option können Scripts mit niedriger Priorität im Lazy-Load-Verfahren geladen werden, wenn der Browser inaktiv ist. Die Funktionen solcher Scripts sind nicht sofort nach der Interaktivität der Seite erforderlich, z. B. Chat- oder Social-Media-Plug-ins.

Entwickler können Next.js mitteilen, wie ihre Anwendung ein Script verwendet, indem sie die Strategie angeben. So kann das Framework Optimierungen und Best Practices für das Laden des Scripts anwenden und gleichzeitig die beste Ladeabfolge sicherstellen.

Mit der Script-Komponente können Entwickler ein Drittanbieter-Script an einer beliebigen Stelle in der Anwendung platzieren, um Drittanbieter-Scripts verzögert zu laden, oder auf Dokumentebene für kritische Scripts. Das bedeutet, dass die Script-Komponente sich an derselben Stelle wie die Komponente befinden kann, die das Script verwendet. Nach der Hydratisierung wird das Script je nach verwendeter Strategie in den Kopf des ursprünglich gerenderten Dokuments oder unten in den Textkörper 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-Scripts messen konnten. Gängige Drittanbieter für Google Tag Manager und Einbettungen in sozialen Medien 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.

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

Der Vorlage für die Commerce App wurden für die Demo wie unten angegeben Drittanbieter-Scripts hinzugefügt.

Vorher Nachher
Google Tag Manager mit asynchroner Ausführung Script-Komponente mit „strategy“ = „afterInteractive“ für beide Scripts
Twitter-Schaltfläche „Folgen“ ohne asynchrone oder verzögerte Ausführung
Konfiguration von Script und Scriptkomponente für Demo 1 mit 2 Scripts

Im folgenden Vergleich ist der visuelle Fortschritt für beide Versionen des Next.js-Commerce-Starter-Kits zu sehen. Wie Sie sehen, wird der LCP mit der Script-Komponente, die mit der richtigen Ladestrategie aktiviert ist, fast eine Sekunde früher erreicht.

Filmstreifenvergleich, der eine Verbesserung des LCP zeigt

Drittanbieter-Scripts in einem Next.js-Blog

Der Demo-Blog-App wurden wie unten angegeben Drittanbieter-Scripts hinzugefügt.

Vorher Nachher
Google Tag Manager mit asynchroner Ausführung Script-Komponente mit „strategy“ = „lazyonload“ für jedes der vier Scripts
Schaltfläche „Twitter folgen“ mit asynchroner Ausführung
YouTube-Schaltfläche „Abonnieren“ ohne asynchrone oder verzögerte Ausführung
LinkedIn-Schaltfläche „Folgen“ ohne asynchrone oder verzögerte Ausführung
Konfiguration von Script und Scriptkomponente für Demo 2 mit 4 Scripts
Video, das den Ladevorgang der Indexseite mit und ohne Script-Komponente zeigt Mit der Script-Komponente konnte eine Verbesserung des FCP um 0,5 Sekunden erzielt werden.

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

Die Zukunft der Script-Komponente

Die Strategieoptionen für afterInteractive und lazyOnload bieten zwar eine erhebliche Kontrolle über renderblockierende Scripts, wir prüfen aber auch andere Optionen, die die Nutzbarkeit der Script-Komponente erhöhen würden.

Web-Worker verwenden

Mit Webworkern können unabhängige Scripts in Hintergrundthreads ausgeführt werden, wodurch der Hauptthread freigegeben wird, um Aufgaben der Benutzeroberfläche zu verarbeiten und die Leistung zu verbessern. Webworker eignen sich am besten, um die JavaScript-Verarbeitung statt der UI-Arbeit vom Haupt-Thread auszulagern. Scripts, die für den Kundensupport oder das Marketing verwendet werden und normalerweise nicht mit der Benutzeroberfläche interagieren, eignen sich gut für die Ausführung in einem Hintergrund-Thread. Mit der schlanken Drittanbieterbibliothek PartyTown können Sie solche Scripts in einem Webworker isolieren.

Bei der aktuellen Implementierung der Next.js-Scriptkomponente empfehlen wir, diese Scripts im Hauptthread zu verschieben, indem Sie die Strategie auf afterInteractive oder lazyOnload festlegen. Künftig möchten wir die Strategieoption 'worker' einführen, mit der Next.js PartyTown oder eine benutzerdefinierte Lösung verwenden kann, um Scripts in Webworkern auszuführen. Wir freuen uns über Feedback von Entwicklern zu diesem RFC.

CLS minimieren

Eingebettete Inhalte von Drittanbietern wie Anzeigen, 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. Sie können den CLS minimieren, indem Sie die Größe des Containers angeben, in dem das eingebettete Element geladen wird.

Mit der Script-Komponente können eingebettete Inhalte geladen werden, die zu Layoutverschiebungen führen können. Wir überlegen, sie um Konfigurationsoptionen zu ergänzen, mit denen sich der CLS reduzieren lässt. Diese Funktion kann innerhalb der Script-Komponente selbst oder als Begleitkomponente verfügbar gemacht werden.

Wrapper-Komponenten

Die Syntax und Ladestrategie für die Einbindung beliebter Drittanbieter-Scripts wie Google Analytics oder Google Tag Manager (GTM) ist in der Regel festgelegt. Diese können für jeden Scripttyp in einzelnen Wrapper-Komponenten gekapselt werden. Entwicklern stehen nur wenige anwendungsspezifische Attribute wie die Tracking-ID zur Verfügung. Wrapper-Komponenten bieten Entwicklern folgende Vorteile:

  1. So können sie beliebte Script-Tags einfacher einbinden.
  2. Das Framework verwendet die optimale Strategie.

Fazit

Drittanbieter-Scripts werden in der Regel erstellt, um bestimmte Funktionen in die Website einzubinden, auf der sie verwendet werden. Um die Auswirkungen nicht kritischer Scripts zu verringern, empfehlen wir, sie zu verschieben. Das geschieht bei der Next.js-Script-Komponente standardmäßig. Entwickler können sich darauf verlassen, dass enthaltene Scripts kritische Funktionen nicht verzögern, es sei denn, sie wenden ausdrücklich die beforeInteractive-Strategie an. Ähnlich wie bei der Next.js-Script-Komponente können Framework-Entwickler diese Funktionen auch in anderen Frameworks implementieren. Wir arbeiten aktiv mit dem Nuxt.js-Team daran, eine ähnliche Komponente zu entwickeln. Basierend auf dem Feedback hoffen wir auch, die Script-Komponente 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.