Laden von Drittanbieterskripts in Next.js optimieren

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

Leena Sohoni
Leena Sohoni
Houssein-Dschirdeh
Houssein Djirdeh

Etwa 45% der Anfragen von Websites, die auf Mobilgeräten und Computern bereitgestellt werden, sind Drittanbieteranfragen. 33% sind Skripts. Die Leistung einer Website kann durch Größe, Latenz und Laden von Drittanbieter-Skripts erheblich beeinträchtigt werden. Die Next.js-Skriptkomponente bietet integrierte Best Practices und Standardeinstellungen, mit denen Entwickler Drittanbieter-Skripts in ihren Anwendungen einbinden und potenzielle Leistungsprobleme von Anfang an beheben können.

Drittanbieter-Skripts und ihre Auswirkung auf die Leistung

Mit Drittanbieter-Skripts können Webentwickler vorhandene Lösungen 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 entsprechenden Website zu berücksichtigen. Diese Skripts sind auch eine Blackbox für Entwickler, die sie verwenden.

Skripts haben eine beträchtliche Anzahl von Drittanbieterbyte, die von Websites für verschiedene Kategorien von Drittanbieteranfragen heruntergeladen werden. Standardmäßig priorisiert der Browser Skripts basierend auf ihrer Position im Dokument. Dies kann das Erkennen oder Ausführen von Skripts verzögern, die für die Nutzerfreundlichkeit wichtig sind.

Für das Layout erforderliche Bibliotheken von Drittanbietern sollten frühzeitig geladen werden, um die Seite zu rendern. Drittanbieter, die nicht für das erste Rendering benötigt werden, sollten zurückgestellt werden, damit sie keine andere Verarbeitung im Hauptthread blockieren. Lighthouse bietet zwei Audits, um Skripts zu kennzeichnen, die das Rendering blockieren oder den Hauptthread blockieren.

Lighthouse-Prüfungen zum Entfernen von Ressourcen, die das Rendering blockieren, und zur Minimierung der Nutzung durch Drittanbieter

Es ist wichtig, die Reihenfolge des Ladens von Ressourcen 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 reduzieren lassen, aber nicht alle Nutzer sind sich darüber im Klaren, wie sie für jeden verwendeten Drittanbieter implementiert werden können. Das kann aus folgenden Gründen kompliziert sein:

  • Websites verwenden durchschnittlich 21 bis 23 verschiedene Drittanbieter, einschließlich Skripts, sowohl auf Mobilgeräten als auch auf Computern. Nutzung und Empfehlungen können sich unterscheiden.
  • Die Implementierung vieler Drittanbieter kann variieren, je nachdem, ob ein bestimmtes Framework oder eine bestimmte UI-Bibliothek verwendet wird.
  • Neuere Bibliotheken von Drittanbietern werden häufig eingeführt.
  • Unterschiedliche Geschäftsanforderungen in Bezug auf einen Drittanbieter erschweren es Entwicklern, die Verwendung zu standardisieren.

Auroras Fokus auf Skripte von Drittanbietern

Teil der Zusammenarbeit mit Open-Source-Web-Frameworks und -Tools besteht darin, starke Standardeinstellungen und fundierte Tools bereitzustellen, um Entwicklern dabei zu helfen, Aspekte der Nutzererfahrung wie Leistung, Barrierefreiheit, Sicherheit und Bereitschaft für Mobilgeräte zu verbessern. 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 Untersuchung der idealen Ladesequenz von Drittanbieter-Skripts in Next.js. Frameworks wie Next.js sind besonders gut dafür geeignet, nützliche Standardeinstellungen und Funktionen bereitzustellen, mit denen Entwickler Ressourcen, einschließlich Drittanbieter-Ressourcen, effizient laden können. Wir haben umfangreiche HTTP Archive- und Lighthouse-Daten untersucht, um herauszufinden, welche Drittanbieter das Rendering auf verschiedenen Frameworks am meisten blockieren.

Um das Problem zu umgehen, dass in einer Anwendung Drittanbieterskripts von Drittanbietern blockiert werden, die Hauptthreads blockiert werden, haben wir die Skriptkomponente entwickelt. Die Komponente kapselt Sequenzfunktionen, um Entwicklern bessere Steuerungsmöglichkeiten für das Laden von Drittanbieter-Skripts zu bieten.

Sequenzierung von Drittanbieter-Skripts ohne Framework-Komponente

Im Leitfaden zur Reduzierung der Auswirkungen von Skripts, die das Rendering blockieren, finden Sie die folgenden Methoden zum effizienten Laden und Sequenzieren von Drittanbieterskripts:

  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 nicht kritisch.

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

Next.js-Skriptkomponente

Die Next.js-Skriptkomponente implementiert die oben genannten Methoden für Sequenzierungsskripts und stellt Entwicklern eine Vorlage zum Definieren ihrer Ladestrategie zur Verfügung. 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 die Möglichkeit, die Ladepriorität für Skripts von Drittanbietern mithilfe des Attributs „Strategie“ festzulegen.

// Example for beforeInteractive:
<Script src="https://polyfill.io/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 wichtige Skripts verwendet werden, die ausgeführt werden sollen, bevor die Seite interaktiv wird. Next.js stellt sicher, dass solche Skripts in den ursprünglichen HTML-Code des Servers eingeschleust und vor anderem selbst gebündeltem JavaScript 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 angewendete Standardstrategie. Sie entspricht dem Laden eines Skripts mit dem Attribut „Aussetzen“. Es wird für Skripts verwendet, die der Browser ausführen kann, nachdem die Seite interaktiv ist, z. B. Analyseskripts. Next.js fügt diese Skripts clientseitig ein. Sie werden ausgeführt, nachdem die Seite hydratisiert wurde. Sofern nicht anders angegeben, werden alle mithilfe der Script-Komponente definierten Drittanbieter-Skripts von Next.js zurückgestellt, wodurch ein starker Standardwert entsteht.

  3. lazyOnload: Diese Option kann zum Lazy Loading von Skripts mit niedriger Priorität verwendet werden, wenn der Browser inaktiv ist. Die von solchen Skripts bereitgestellten Funktionen werden nicht sofort benötigt, nachdem die Seite interaktiv wird, z. B. Chat oder Plug-ins für soziale Medien.

Entwickler können Next.js mitteilen, wie ihre Anwendung ein Skript verwendet, indem sie die Strategie festlegen. Auf diese Weise kann das Framework Optimierungen und Best Practices anwenden, um das Skript zu laden und gleichzeitig für die beste Ladesequenz zu sorgen.

Mit der Script-Komponente können Entwickler ein Drittanbieterskript überall in der Anwendung platzieren, damit Drittanbieter spät laden, und auf Dokumentebene für wichtige Skripts. Dies impliziert, dass die Skriptkomponente zusammen mit der Komponente unter Verwendung des Skripts platziert werden könnte. Nach der Flüssigkeitszufuhr wird das Skript je nach verwendeter Strategie in den Kopf des ursprünglich gerenderten Dokuments oder am unteren Rand des Körpers 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 der Einbindung von Drittanbieterskripts gemessen werden konnten. Häufig verwendete Drittanbieter für Google Tag Manager und Einbettungen in soziale Medien wurden zuerst direkt auf den Seiten dieser Apps und dann über die Script-Komponente eingefügt. 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 wurden Drittanbieter-Skripts für die Demo hinzugefügt, wie unten dargestellt.

Vorher Nachher
Google Tag Manager mit asynchronen Skriptkomponente mit Strategie = afterInteractive für beide Skripts
Twitter-Schaltfläche „Folgen“ ohne Asynchron oder Verzögerung
Konfiguration der Skript- und Skriptkomponenten für Demo 1 mit zwei Skripts.

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

Filmstreifenvergleich mit Verbesserung des LCP-Werts

Skripts von Drittanbietern in einem Next.js-Blog

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

Vorher Nachher
Google Tag Manager mit asynchronen Skriptkomponente mit Strategie = Lazyonload für jedes der vier Skripts
Twitter Follow-Schaltfläche mit asynchronem
YouTube-Schaltfläche „Abonnieren“ ohne Asynchronität oder Verzögerung
LinkedIn-Schaltfläche „Folgen“ ohne Asynchron oder Verzögerung
Konfiguration der Skript- und Skriptkomponenten für Demo 2 mit 4 Skripts
Video, das den Ladefortschritt für die Indexseite mit und ohne Skriptkomponente zeigt Durch die Skript-Komponente kann der FCP-Wert um 0,5 Sekunden verbessert werden.

Wie im Video zu sehen ist, wird First Contentful Paint (FCP) bei 0,9 Sekunden ohne die Skriptkomponente und 0,4 Sekunden mit der Skriptkomponente auf der Seite ausgeführt.

Nächste Schritte bei der Skriptkomponente

Die Strategieoptionen für afterInteractive und lazyOnload bieten zwar weitreichende Kontrolle über Skripts, die das Rendering blockieren, wir arbeiten aber auch an anderen Optionen, mit denen die Skriptkomponente noch nützlicher wird.

Web-Worker verwenden

Mit Web Workern können unabhängige Skripts in Hintergrundthreads ausgeführt werden, sodass der Hauptthread für die Verarbeitung von Aufgaben der Benutzeroberfläche freigegeben und die Leistung verbessert werden kann. Web Worker eignen sich am besten, um die JavaScript-Verarbeitung statt UI-Arbeiten aus dem Hauptthread auszulagern. Skripts für den Kundensupport oder das Marketing, die normalerweise nicht mit der Benutzeroberfläche interagieren, eignen sich gut für die Ausführung in einem Hintergrundthread. Eine einfache Drittanbieterbibliothek – PartyTown – kann verwendet werden, um solche Skripts in einem Web Worker zu isolieren.

Bei der aktuellen Implementierung der Next.js-Skriptkomponente empfehlen wir, diese Skripts im Hauptthread zurückzustellen, indem Sie die Strategie auf afterInteractive oder lazyOnload setzen. Für die Zukunft schlagen wir die Einführung der neuen Strategie 'worker' vor. 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 Werbung, Videos oder Feeds in sozialen Medien können bei Lazy Loading zu Layoutverschiebungen führen. Dies wirkt sich auf die Nutzerfreundlichkeit und den Messwert Cumulative Layout Shift (CLS) für die Seite aus. Sie können CLS minimieren, indem Sie die Größe des Containers angeben, in den die Einbettung geladen werden soll.

Die Skriptkomponente kann zum Laden von Einbettungen verwendet werden, die Layoutverschiebungen verursachen können. Wir erwägen eine Erweiterung, um Konfigurationsoptionen bereitzustellen, mit denen der CLS-Wert reduziert werden kann. Diese kann in der Skript-Komponente selbst oder als Companion-Komponente zur Verfügung gestellt werden.

Wrapper-Komponenten

Syntax und Ladestrategie beim Einbinden gängiger 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 eine minimale Gruppe anwendungsspezifischer Attribute zur Verfügung (z. B. Tracking-ID). Wrapper-Komponenten bieten Entwicklern folgende Vorteile:

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

Fazit

Drittanbieter-Skripts werden normalerweise erstellt, um bestimmte Funktionen in die entsprechende Website einzubinden. Um die Auswirkungen nicht kritischer Skripts zu reduzieren, empfehlen wir, diese zu verschieben. Dies ist von der Next.js-Skriptkomponente standardmäßig der Fall. Entwickler können sich darauf verlassen, dass über Skripts wichtige Funktionen nicht verzögert werden, es sei denn, sie wenden die Strategie „beforeInteractive“ ausdrücklich an. Wie die Next.js-Skriptkomponente können Framework-Entwickler diese Funktionen auch in anderen Frameworks erstellen. Wir arbeiten gemeinsam mit dem Nuxt.js-Team intensiv an einer Lösung für eine ähnliche Komponente. Basierend auf dem Feedback 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.