Een Next.js-pakket voor het beheren van bibliotheken van derden

Houssein Djirdeh
Houssein Djirdeh

In 2021 introduceerde het Chrome Aurora-team de Script-component om de laadprestaties van scripts van derden in Next.js te verbeteren. Sinds de lancering hebben we de mogelijkheden ervan uitgebreid om het laden van bronnen van derden eenvoudiger en sneller te maken voor ontwikkelaars.

In deze blogpost geven we een overzicht van de nieuwe functies die we hebben uitgebracht, met name de @next/third-partys -bibliotheek. Ook geven we een overzicht van toekomstige initiatieven op onze roadmap.

Prestatie-implicaties van scripts van derden

41% van alle verzoeken van derden op Next.js-sites zijn scripts. In tegenstelling tot andere contenttypen kan het downloaden en uitvoeren van scripts aanzienlijk lang duren, wat de weergave kan blokkeren en de interactie met de gebruiker kan vertragen. Gegevens uit het Chrome User Experience Report (CrUX) tonen aan dat Next.js-sites die meer scripts van derden laden, lagere Interaction to Next Paint (INP) en Largest Contentful Paint (LCP) slagingspercentages hebben.

Staafdiagram dat een daling laat zien in het percentage Next.js dat goede INP- en LCP-scores behaalt in verhouding tot het aantal geladen derde partijen
CrUX-rapport december 2023 (110.823 sites)

De correlatie die in deze grafiek wordt waargenomen, impliceert geen causaliteit. Lokale experimenten leveren echter aanvullend bewijs dat scripts van derden een aanzienlijke impact hebben op de paginaprestaties. De onderstaande grafiek vergelijkt bijvoorbeeld verschillende labstatistieken wanneer een Google Tag Manager-container – bestaande uit 18 willekeurig geselecteerde tags – wordt toegevoegd aan Taxonomy , een populaire Next.js-voorbeeldapp.

Staafdiagram dat het verschil in verschillende labstatistieken laat zien wanneer een site met en zonder Google Tag Manager wordt geladen
WebPageTest (Mobiel 4G - Virginia, VS)

De documentatie van WebPageTest biedt details over hoe deze timings worden gemeten. Een snelle blik leert dat al deze labstatistieken worden beïnvloed door de GTM-container. Zo nam de Total Blocking Time (TBT) – een handige labproxy die de INP benadert – bijna twintig keer toe.

Scriptcomponent

Toen we de <Script> -component in Next.js introduceerden, zorgden we ervoor dat deze werd geïntroduceerd via een gebruiksvriendelijke API die sterk lijkt op het traditionele <script> -element. Door deze API te gebruiken, kunnen ontwikkelaars een script van een derde partij in elke component van hun applicatie plaatsen, en Next.js zorgt voor de sequentie van het script nadat kritieke resources zijn geladen.

<!-- By default, script will load after page becomes interactive -->
<Script src="https://example.com/sample.js" />

<!-- Script is injected server-side and fetched before any page hydration occurs -->
<Script strategy=”beforeInteractive” src="https://example.com/sample.js" />

<!-- Script is fetched later during browser idle time -->
<Script strategy=”lazyOnload” src="https://example.com/sample.js" />

Tienduizenden Next.js-applicaties, waaronder populaire sites zoals Patreon , Target en Notion , gebruiken de <Script> -component. Ondanks de effectiviteit ervan, hebben sommige ontwikkelaars hun zorgen geuit over de volgende zaken:

  • Waar u het <Script> -component in een Next.js-app moet plaatsen, rekening houdend met de verschillende installatie-instructies van verschillende externe leveranciers (ervaring van de ontwikkelaar) .
  • Welke laadstrategie is het meest optimaal voor verschillende scripts van derden (gebruikerservaring) .

Om beide zorgen aan te pakken, hebben we @next/third-parties gelanceerd: een gespecialiseerde bibliotheek met een set geoptimaliseerde componenten en hulpprogramma's die speciaal zijn afgestemd op populaire externe partijen.

Ontwikkelaarservaring: het beheer van bibliotheken van derden eenvoudiger maken

Veel scripts van derden worden gebruikt in een aanzienlijk percentage van de Next.js-sites, waarbij Google Tag Manager het populairst is en door respectievelijk 66% van de sites wordt gebruikt. @next/third-parties bouwt voort op het <Script> -component door wrappers op een hoger niveau te introduceren die zijn ontworpen om het gebruik voor deze veelvoorkomende use cases te vereenvoudigen.

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleTagManager gtmId="GTM-XYZ" />
    </html>
  );
}

Google Analytics, een ander veelgebruikt script van derden ( 52% van de Next.js-sites ), heeft ook een eigen component.

import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <GoogleAnalytics gaId="G-XYZ" />
    </html>
  );
}

@next/third-parties vereenvoudigt het laden van veelgebruikte scripts, maar biedt ons ook de mogelijkheid om hulpprogramma's te ontwikkelen voor andere categorieën van derden, zoals embeds. Zo worden Google Maps en YouTube embeds gebruikt in respectievelijk 8% en 4% van de Next.js-websites, en we hebben ook componenten meegeleverd om ze gemakkelijker te laden.

import { GoogleMapsEmbed } from "@next/third-parties/google";
import { YouTubeEmbed } from "@next/third-parties/google";

export default function Page() {
  return (
    <>
      <GoogleMapsEmbed
        apiKey="XYZ"
        height={200}
        width="100%"
        mode="place"
        q="Brooklyn+Bridge,New+York,NY"
      />
      <YouTubeEmbed videoid="ogfYd705cRs" height={400} params="controls=0" />
    </>
  );
}

Gebruikerservaring: bibliotheken van derden sneller laten laden

In een ideale wereld zou elke veelgebruikte bibliotheek van derden volledig geoptimaliseerd zijn, waardoor abstracties die de prestaties verbeteren overbodig worden. Totdat dit echter werkelijkheid wordt, kunnen we proberen de gebruikerservaring te verbeteren door deze te integreren via populaire frameworks zoals Next.js. We kunnen experimenteren met verschillende laadtechnieken, ervoor zorgen dat scripts op de juiste manier worden gesequenced en uiteindelijk onze feedback delen met externe leveranciers om upstream-wijzigingen te stimuleren.

Neem bijvoorbeeld YouTube embeds. Sommige alternatieve implementaties presteren veel beter dan de native embed. Momenteel gebruikt de <YouTubeEmbed> -component die door @next/third-parties wordt geëxporteerd lite-youtube-embed , wat, zoals gedemonstreerd in een "Hello, World" Next.js-vergelijking, aanzienlijk sneller laadt.

GIF die een vergelijking laat zien van de paginalading tussen het YouTube Embed-component en een normaal YouTube-iframe
WebPageTest (Mobiel 4G - Virginia, VS)

Op dezelfde manier voegen we voor Google Maps loading="lazy" toe als standaardkenmerk voor de embed om ervoor te zorgen dat de kaart alleen laadt wanneer deze zich op een bepaalde afstand van de viewport bevindt. Dit lijkt misschien een voor de hand liggend kenmerk, vooral omdat de Google Maps- documentatie het in hun voorbeeldcodefragment opneemt, maar slechts 45% van de Next.js-sites die Google Maps embedden, gebruikt loading="lazy" .

Scripts van derden uitvoeren in een webworker

Een geavanceerde techniek die we in @next/third-parties onderzoeken, is het eenvoudiger maken om scripts van derden naar een webworker te verplaatsen. Deze techniek, die populair is gemaakt door bibliotheken zoals Partytown , kan de impact van scripts van derden op de paginaprestaties aanzienlijk verminderen door ze volledig buiten de hoofdthread te plaatsen.

De volgende geanimeerde GIF toont de variaties in lange taken en de blokkeringstijd van de hoofdthread bij het toepassen van verschillende <Script> -strategieën op een GTM-container binnen een Next.js-site. Merk op dat, hoewel het schakelen tussen strategieopties alleen de timing van de uitvoering van deze scripts vertraagt, het verplaatsen ervan naar een webworker hun tijd op de hoofdthread volledig elimineert.

GIF die de verschillen in blokkeringstijd van de hoofdthread voor de verschillende scriptstrategieën laat zien
WebPageTest (Mobiel 4G - Virginia, VS)

In dit specifieke voorbeeld werd de TBT met 92% verlaagd door de uitvoering van de GTM-container en de bijbehorende tagscripts te verplaatsen naar een webworker.

Het is belangrijk om te weten dat deze techniek, indien niet zorgvuldig beheerd, veel scripts van derden onopgemerkt kan verstoren, waardoor debuggen lastig wordt. In de komende maanden zullen we valideren of componenten van derden die door @next/third-parties worden aangeboden correct functioneren wanneer ze in een webworker worden uitgevoerd. Zo ja, dan werken we aan een eenvoudige, optionele manier voor ontwikkelaars om deze techniek te gebruiken.

Volgende stappen

Tijdens de ontwikkeling van dit pakket werd duidelijk dat er behoefte was aan het centraliseren van laadaanbevelingen van derden, zodat andere frameworks ook konden profiteren van dezelfde onderliggende technieken. Dit leidde tot de ontwikkeling van Third Party Capital , een bibliotheek die JSON gebruikt om laadtechnieken van derden te beschrijven. Deze bibliotheek vormt momenteel de basis voor @next/third-parties .

Onze volgende stappen zijn het verbeteren van de componenten voor Next.js en het uitbreiden van onze inspanningen om vergelijkbare hulpprogramma's te integreren in andere populaire frameworks en CMS-platforms. We werken momenteel samen met Nuxt-beheerders en zijn van plan om in de nabije toekomst vergelijkbare hulpprogramma's van derden te lanceren, afgestemd op hun ecosysteem.

Als een van de externe partijen die je in je Next.js-app gebruikt, wordt ondersteund door @next/third-parties , installeer dan het pakket en probeer het eens! We horen graag je feedback op GitHub .