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

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 uitgebreid om het laden van bronnen van derden voor ontwikkelaars eenvoudiger en sneller te maken.

Deze blogpost biedt een overzicht van de nieuwere functies die we hebben uitgebracht, met name de @next/third-parties -bibliotheek, evenals een overzicht van toekomstige initiatieven op onze routekaart.

Prestatie-implicaties van scripts van derden

41% van alle verzoeken van derden op Next.js-sites zijn scripts. In tegenstelling tot andere inhoudstypen kan het downloaden en uitvoeren van scripts een aanzienlijke hoeveelheid tijd in beslag nemen, waardoor de weergave kan worden geblokkeerd en de interactiviteit van de gebruiker kan worden vertraagd. Uit gegevens uit het Chrome User Experience Report (CrUX) blijkt dat Next.js-sites die meer scripts van derden laden, lagere slagingspercentages voor Interaction to Next Paint (INP) en Largest Contentful Paint (LCP) 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
December 2023 Crux-rapport (110.823 sites)

De correlatie die in deze grafiek wordt waargenomen, impliceert geen oorzakelijk verband. Lokale experimenten leveren echter aanvullend bewijs dat scripts van derden de paginaprestaties aanzienlijk beïnvloeden. In het onderstaande diagram worden bijvoorbeeld verschillende labstatistieken vergeleken 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 laat zien in verschillende laboratoriumstatistieken wanneer een site wordt geladen met en zonder Google Tag Manager
WebPageTest (Mobiel 4G - Virginia, VS)

De WebPageTest- documentatie biedt details over hoe deze timings worden gemeten. In één oogopslag is het duidelijk dat al deze laboratoriumstatistieken worden beïnvloed door de GTM-container. De Total Blocking Time (TBT) – een nuttige laboratoriumproxy die de INP benadert – kende bijvoorbeeld een bijna twintigvoudige toename.

Scriptcomponent

Toen we de <Script> -component in Next.js uitbrachten, hebben we ervoor gezorgd dat we deze introduceerden via een gebruiksvriendelijke API die sterk lijkt op het traditionele <script> -element. Door het te gebruiken kunnen ontwikkelaars een script van derden in elk onderdeel van hun applicatie plaatsen, en Next.js zorgt voor de volgorde van het script nadat kritieke bronnen 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 de <Script> -component in een Next.js-app te plaatsen, terwijl u zich houdt aan de variërende installatie-instructies van verschillende externe providers (ervaring van ontwikkelaars) .
  • Welke laadstrategie is het meest optimaal om te gebruiken voor verschillende scripts van derden (gebruikerservaring) .

Om beide problemen aan te pakken, hebben we @next/third-parties gelanceerd: een gespecialiseerde bibliotheek die een reeks geoptimaliseerde componenten en hulpprogramma's biedt, op maat gemaakt voor populaire derde partijen.

Ontwikkelaarservaring: bibliotheken van derden eenvoudiger te beheren

In een aanzienlijk percentage van de Next.js-sites worden veel scripts van derden gebruikt, waarbij Google Tag Manager het populairst is en door respectievelijk 66% van de sites wordt gebruikt. @next/third-parties bouwt voort op de <Script> -component door wrappers op een hoger niveau te introduceren, ontworpen om het gebruik voor deze veelvoorkomende gebruiksscenario's 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 speciaal eigen onderdeel.

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 proces van het laden van veelgebruikte scripts, maar breidt ook onze mogelijkheden uit om hulpprogramma's te ontwikkelen voor andere categorieën van derden, zoals insluitingen. Insluitingen van Google Maps en YouTube worden bijvoorbeeld gebruikt in respectievelijk 8% en 4% van de Next.js-websites, en we hebben ook componenten geleverd om ze gemakkelijker te kunnen 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 laden

In een perfecte wereld zou elke algemeen aanvaarde bibliotheek van derden volledig geoptimaliseerd zijn, waardoor alle abstracties die de prestaties verbeteren overbodig worden. Totdat dit echter werkelijkheid wordt, kunnen we proberen hun gebruikerservaring te verbeteren wanneer ze worden geïntegreerd via populaire raamwerken zoals Next.js. We kunnen experimenteren met verschillende laadtechnieken, ervoor zorgen dat scripts op de juiste manier worden geordend en uiteindelijk onze feedback delen met externe providers om upstream-wijzigingen aan te moedigen.

Neem bijvoorbeeld YouTube-embeds. Waar sommige alternatieve implementaties veel betere prestaties leveren dan de native embed. Momenteel gebruikt de <YouTubeEmbed> -component die wordt geëxporteerd door @next/third-parties lite-youtube-embed , dat, wanneer gedemonstreerd in een "Hallo, wereld" Next.js-vergelijking, aanzienlijk sneller laadt.

GIF die de vergelijking van de paginalading toont tussen de YouTube Embed-component en een regulier YouTube-iframe
WebPageTest (Mobiel 4G - Virginia, VS)

Op dezelfde manier nemen we voor Google Maps loading="lazy" op als standaardkenmerk voor de insluiting om ervoor te zorgen dat de kaart alleen wordt geladen als deze zich op een bepaalde afstand van de viewport bevindt. Dit lijkt misschien een voor de hand liggend attribuut om op te nemen (vooral omdat de Google Maps- documentatie dit in hun voorbeeldcodefragment opneemt), maar slechts 45% van de Next.js-sites die Google Maps insluiten, gebruikt loading="lazy" .

Scripts van derden uitvoeren in een webwerker

Een geavanceerde techniek die we in @next/third-parties onderzoeken, is het gemakkelijker maken om de scripts van derden over te dragen aan een webwerker. Gepopulariseerd door bibliotheken zoals Partytown , kan dit de impact van scripts van derden op de prestaties van de pagina aanzienlijk verminderen door ze volledig buiten de hoofdthread te verplaatsen.

De volgende geanimeerde GIF toont de variaties in lange taken en blokkeringstijd van de hoofdthread bij het toepassen van verschillende <Script> -strategieën op een GTM-container binnen een Next.js-site. Houd er rekening mee dat, hoewel het schakelen tussen strategieopties alleen maar de timing vertraagt ​​waarop deze scripts worden uitgevoerd, het verplaatsen ervan naar een webwerker de tijd die ze aan de hoofdthread besteden volledig elimineert.

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

In dit specifieke voorbeeld verminderde het verplaatsen van de uitvoering van de GTM-container en de bijbehorende tagscripts naar een webwerker de TBT met 92% .

Het is vermeldenswaard dat deze techniek, als deze niet zorgvuldig wordt beheerd, in stilte veel scripts van derden kan breken, waardoor het debuggen een uitdaging wordt. In de komende maanden zullen we valideren of componenten van derden die worden aangeboden door @next/third-parties correct functioneren wanneer ze worden uitgevoerd in een webwerker. Als dat zo is, zullen we eraan werken om ontwikkelaars een gemakkelijke en optionele manier te bieden om deze techniek te gebruiken.

Volgende stappen

Tijdens het ontwikkelingsproces van dit pakket werd het duidelijk dat er behoefte was aan het centraliseren van laadaanbevelingen van derden, zodat andere raamwerken ook konden profiteren van dezelfde gebruikte onderliggende technieken. Dit bracht ons ertoe Third Party Capital te bouwen, een bibliotheek die JSON gebruikt om laadtechnieken van derden te beschrijven, die momenteel als basis dient voor @next/third-parties .

Als volgende stappen zullen we ons blijven concentreren op het verbeteren van de componenten voor Next.js en onze inspanningen uitbreiden om soortgelijke hulpprogramma's op te nemen in andere populaire frameworks en CMS-platforms. We werken momenteel samen met Nuxt-beheerders en zijn van plan in de nabije toekomst vergelijkbare hulpprogramma's van derden uit te brengen die zijn afgestemd op hun ecosysteem.

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