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 ausgeliefert werden, sind Drittanbieteranfragen, von denen 33% Skripts sind. Größe, Latenz und Laden von Drittanbieterskripts können die Leistung einer Website erheblich beeinträchtigen. Die Next.js-Script-Komponente enthält integrierte Best Practices und Standardeinstellungen, mit denen Entwickler Drittanbieter-Scripts in ihre Anwendungen einfügen und potenzielle Leistungsprobleme von vornherein vermeiden können.

Drittanbieterskripts und ihre Auswirkungen auf die Leistung

Mit Drittanbieterskripts 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 Website zu berücksichtigen. Diese Skripts sind auch für Entwickler, die sie verwenden, eine Blackbox.

Scripts 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 darauf, wo sie sich im Dokument befinden. Dadurch kann es zu Verzögerungen bei der Erkennung oder Ausführung von Skripts kommen, die für die Nutzerfreundlichkeit entscheidend sind.

Drittanbieterbibliotheken, die für das Layout erforderlich sind, sollten frühzeitig geladen werden, damit die Seite gerendert werden kann. Drittanbieter, die für das erste Rendering nicht erforderlich sind, sollten verzögert werden, damit sie andere Verarbeitungsvorgänge im Hauptthread nicht blockieren. Lighthouse bietet zwei Prüfungen, mit denen Skripts gekennzeichnet werden, die das Rendern blockieren oder den Haupt-Thread blockieren.

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

Es ist wichtig, die Reihenfolge zu berücksichtigen, in der Ressourcen auf Ihrer Seite geladen werden, damit kritische Ressourcen nicht verzögert werden und nicht kritische Ressourcen kritische Ressourcen nicht blockieren.

Es gibt zwar Best Practices, um die Auswirkungen von Drittanbietern zu minimieren, aber nicht jeder weiß, wie er sie für jeden verwendeten Drittanbieter implementieren kann. Das kann kompliziert sein, weil:

  • Im Durchschnitt verwenden Websites auf Mobilgeräten und Computern 21 bis 23 verschiedene Drittanbieter, einschließlich Skripts. Die Nutzung und Empfehlungen können sich für die einzelnen Produkte unterscheiden.
  • Die Implementierung vieler Drittanbieter kann sich je nach verwendetem Framework oder der verwendeten UI-Bibliothek unterscheiden.
  • Es werden häufig neuere Drittanbieterbibliotheken eingeführt.
  • Unterschiedliche geschäftliche Anforderungen in Bezug auf denselben Drittanbieter erschweren es Entwicklern, die Verwendung zu standardisieren.

Fokus von Aurora auf Drittanbieterskripts

Im Rahmen der Zusammenarbeit von Aurora mit Open-Source-Webframeworks und ‑Tools werden starke Standardeinstellungen und meinungsstarke Tools bereitgestellt, mit denen Entwickler Aspekte der Nutzerfreundlichkeit wie Leistung, Barrierefreiheit, Sicherheit und Optimierung für Mobilgeräte 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 Untersuchung der idealen Ladereihenfolge von Drittanbieter-Scripts in Next.js. Frameworks wie Next.js bieten nützliche Standardeinstellungen und Funktionen, mit denen Entwickler Ressourcen, einschließlich Drittanbieterressourcen, effizient laden können. Wir haben umfangreiche HTTP Archive- und Lighthouse-Daten analysiert, um herauszufinden, welche Drittanbieter in den verschiedenen Frameworks am häufigsten das Rendern blockieren.

Um das Problem von Drittanbieter-Skripts zu beheben, die den Hauptthread einer Anwendung blockieren, haben wir die Script-Komponente entwickelt. Die Komponente kapselt Sequenzierungsfunktionen, um Entwicklern bessere Kontrollmöglichkeiten für das Laden von Drittanbieterskripts zu bieten.

Drittanbieter-Scripts ohne Framework-Komponente sequenzieren

Die verfügbaren Anleitungen zur Reduzierung der Auswirkungen von renderblockierenden Skripten bieten die folgenden Methoden zum effizienten Laden und Sequenzieren von Drittanbieterskripten:

  1. Verwenden Sie das Attribut async oder defer mit <script>-Tags, um dem Browser mitzuteilen, dass nicht kritische Drittanbieter-Skripts geladen werden sollen, ohne den Dokumentparser zu blockieren. Skripts, 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. Frühzeitige Verbindungen zu erforderlichen Quellen herstellen – mit preconnect und dns-prefetch. 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 für Ressourcen und Einbettungen von Drittanbietern sollte erst erfolgen, 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 zum Anordnen von Skripten und bietet eine Vorlage, mit der Entwickler ihre Ladestrategie definieren können. Sobald die geeignete Strategie angegeben 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 wichtige 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 anderem selbst gebündelten JavaScript ausgeführt werden. Skripts zur Einwilligungsverwaltung, zur Bot-Erkennung oder Hilfsbibliotheken, die zum Rendern wichtiger Inhalte erforderlich sind, eignen sich gut für diese Strategie.

  2. afterInteractive: Dies ist die standardmäßig angewendete Strategie. 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. Sie werden ausgeführt, nachdem die Seite gerendert wurde. Sofern nicht anders angegeben, werden alle Drittanbieter-Scripts, die mit der Script-Komponente definiert werden, von Next.js verzögert. Das ist eine gute Standardeinstellung.

  3. lazyOnload: Mit dieser Option können Sie Skripts mit niedriger Priorität verzögert laden, wenn der Browser im Leerlauf ist. Die von solchen Skripts bereitgestellten Funktionen sind nicht unmittelbar 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 Skript verwendet, indem sie die Strategie angeben. So kann das Framework Optimierungen und Best Practices anwenden, um das Skript zu laden und gleichzeitig die beste Ladesequenz zu gewährleisten.

Mit der Script-Komponente können Entwickler ein Drittanbieter-Script an einer beliebigen Stelle in der Anwendung platzieren, um Drittanbieter-Scripts spät zu laden, und auf Dokumentebene für kritische Scripts. Das bedeutet, dass sich die Script-Komponente möglicherweise am selben Ort wie die Komponente befindet, die das Script verwendet. Nach der Hydrierung wird das Skript in den Head des ursprünglich gerenderten Dokuments oder unten in den Body eingefügt, je nach verwendeter Strategie.

Auswirkungen 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. 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.

Drittanbieterskripts in einer Next.js-Commerce-App

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

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

Im folgenden Vergleich wird der visuelle Fortschritt für beide Versionen des Next.js Commerce Starter-Kits dargestellt. Wie Sie sehen, tritt LCP mit der Script-Komponente und der richtigen Ladestrategie fast eine Sekunde früher auf.

Vergleich von Filmstreifen, der eine Verbesserung des LCP-Werts zeigt

Drittanbieterskripts in einem Next.js-Blog

Der Demoblog-App wurden Drittanbieterskripts wie unten beschrieben hinzugefügt.

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

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

Nächste Schritte für die Script-Komponente

Die Strategieoptionen für afterInteractive und lazyOnload bieten zwar eine erhebliche Kontrolle über das Rendern blockierende Skripts, wir prüfen aber auch andere Optionen, die die Nützlichkeit der Script-Komponente erhöhen würden.

Web-Worker verwenden

Web Workers können verwendet werden, um unabhängige Skripts in Hintergrundthreads auszuführen. So kann der Hauptthread für die Verarbeitung von Aufgaben der Benutzeroberfläche freigegeben und die Leistung verbessert werden. Web Workers eignen sich am besten, um die JavaScript-Verarbeitung und nicht die UI-Arbeit vom Haupt-Thread zu entlasten. Skripts, die für den Kundensupport oder das Marketing verwendet werden und in der Regel nicht mit der Benutzeroberfläche interagieren, eignen sich möglicherweise gut für die Ausführung in einem Hintergrundthread. Mit der schlanken Drittanbieterbibliothek PartyTown können solche Skripts in einem Web-Worker isoliert werden.

Bei der aktuellen Implementierung der Next.js-Script-Komponente empfehlen wir, diese Skripts im Hauptthread zu verzögern, indem Sie die Strategie auf afterInteractive oder lazyOnload festlegen. Wir schlagen vor, in Zukunft eine neue Strategieoption einzuführen: 'worker'. Damit kann Next.js PartyTown oder eine benutzerdefinierte Lösung verwenden, um Skripts in Webworkern auszuführen. Wir freuen uns über Kommentare von Entwicklern zu diesem RFC.

CLS minimieren

Einbettungen von Drittanbietern wie Anzeigen, Videos oder Social-Media-Feeds können bei 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 lässt sich minimieren, indem Sie die Größe des Containers angeben, in den das Embed geladen wird.

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

Wrapper-Komponenten

Die Syntax und Ladestrategie für die Einbindung beliebter Drittanbieterskripts 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 steht nur eine Mindestanzahl an anwendungsspezifischen Attributen (z. B. Tracking-ID) zur Verfügung. Wrapper-Komponenten bieten Entwicklern folgende Vorteile:

  1. So können sie beliebte Skript-Tags leichter einfügen.
  2. Das Framework verwendet im Hintergrund die optimale Strategie.

Fazit

Drittanbieterscripts werden in der Regel erstellt, um bestimmte Funktionen in die verwendende Website einzubinden. Um die Auswirkungen nicht kritischer Skripts zu verringern, empfehlen wir, sie aufzuschieben. Das geschieht standardmäßig mit der Next.js-Script-Komponente. Entwickler können sich darauf verlassen, dass enthaltene Skripts kritische Funktionen nicht verzögern, es sei denn, sie wenden explizit die beforeInteractive-Strategie an. Wie bei der Next.js-Script-Komponente können Framework-Entwickler auch in anderen Frameworks diese Funktionen entwickeln. 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.