Un pacchetto Next.js per la gestione delle librerie di terze parti

Nel 2021, il team di Chrome Aurora ha introdotto il componente Script per migliorare le prestazioni di caricamento degli script di terze parti in Next.js. Dal suo lancio, ne abbiamo ampliato le funzionalità per semplificare e velocizzare il caricamento delle risorse di terze parti per gli sviluppatori.

Questo post del blog fornisce una panoramica delle funzionalità più recenti che abbiamo rilasciato, in particolare la raccolta @next/third-parties, nonché una panoramica delle iniziative future nella nostra roadmap.

Implicazioni sul rendimento degli script di terze parti

Il 41% di tutte le richieste di terze parti nei siti Next.js sono script. A differenza di altri tipi di contenuti, il download e l'esecuzione degli script possono richiedere molto tempo, il che può bloccare il rendering e ritardare l'interattività dell'utente. I dati del report sull'esperienza utente di Chrome (CrUX) mostrano che i siti Next.js che caricano più script di terze parti hanno percentuali di superamento più basse di Interaction to Next Paint (INP) e Largest Contentful Paint (LCP).

Grafico a barre che mostra una diminuzione della percentuale di Next.js che raggiunge buoni punteggi INP e LCP in proporzione al numero di terze parti caricate
Report CrUX di dicembre 2023 (110.823 siti)

La correlazione osservata in questo grafico non implica una relazione di causa-effetto. Tuttavia, gli esperimenti locali forniscono ulteriori prove del fatto che gli script di terze parti hanno un impatto significativo sul rendimento della pagina. Ad esempio, il grafico riportato di seguito mette a confronto varie metriche dei lab quando un contenitore di Google Tag Manager, composto da 18 tag selezionati casualmente, viene aggiunto a Taxonomy, una popolare app di esempio Next.js.

Grafico a barre che mostra la differenza nelle varie metriche dei lab quando un sito viene caricato con e senza Google Tag Manager
WebPageTest (4G mobile - Virginia USA)

La documentazione di WebPageTest fornisce dettagli su come vengono misurati questi tempi. A prima vista, è chiaro che tutte queste metriche del lab sono interessate dal contenitore GTM. Ad esempio, il Tempo di blocco totale (TBT), un utile proxy per i lab che approssima l'INP, ha registrato un aumento di quasi 20 volte.

Componente script

Quando abbiamo spedito il componente <Script> in Next.js, ci siamo assicurati di introdurlo tramite un'API facile da usare che assomiglia molto all'elemento <script> tradizionale. Utilizzandolo, gli sviluppatori possono collocare uno script di terze parti in qualsiasi componente dell'applicazione e Next.js si occuperà di sequenziare lo script dopo il caricamento delle risorse critiche.

<!-- 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" />

Decine di migliaia di applicazioni Next.js, tra cui siti molto noti come Patreon, Target e Notion, utilizzano il componente <Script>. Nonostante la sua efficacia, alcuni sviluppatori hanno sollevato dubbi in merito a quanto segue:

  • Dove posizionare il componente <Script> in un'app Next.js rispettando le varie istruzioni di installazione di diversi provider di terze parti (esperienza degli sviluppatori).
  • Quale strategia di caricamento è la più ottimale da utilizzare per diversi script di terze parti (esperienza utente).

Per rispondere a entrambe queste preoccupazioni, abbiamo lanciato @next/third-parties, una libreria specializzata che offre una serie di componenti e utilità ottimizzati su misura per le terze parti più diffuse.

Esperienza di sviluppo: semplificare la gestione delle librerie di terze parti

Molti script di terze parti vengono utilizzati in una percentuale significativa di siti Next.js, mentre Google Tag Manager è il più popolare, utilizzato rispettivamente dal 66% dei siti. @next/third-parties si basa sul componente <Script> introducendo wrapper di livello superiore progettati per semplificare l'utilizzo in questi casi d'uso comuni.

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

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

Anche Google Analytics, un altro script di terze parti ampiamente utilizzato (52% dei siti Next.js), ha un componente dedicato.

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 semplifica il processo di caricamento degli script di uso comune, ma estende anche la nostra capacità di sviluppare utilità per altre categorie di terze parti, come gli incorporamenti. Ad esempio, gli incorporamenti di Google Maps e YouTube sono utilizzati rispettivamente nell'8% e nel 4% dei siti web Next.js. Inoltre, abbiamo spedito componenti che ne facilitano il caricamento.

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" />
    </>
  );
}

Esperienza utente: velocizzare il caricamento delle librerie di terze parti

In un mondo perfetto, ogni libreria di terze parti ampiamente utilizzata verrebbe completamente ottimizzata, rendendo inutili eventuali astrazioni che ne migliorano le prestazioni. Tuttavia, finché ciò non diventerà effettivo, possiamo provare a migliorare l'esperienza utente dell'utente integrandolo tramite framework popolari come Next.js. Possiamo sperimentare diverse tecniche di caricamento, assicurarci che gli script siano sequenziati nel modo giusto e infine condividere il nostro feedback con provider di terze parti per incoraggiare modifiche a monte.

Prendiamo come esempio gli incorporamenti di YouTube. mentre alcune implementazioni alternative offrono prestazioni di gran lunga migliori rispetto all'incorporamento nativo. Attualmente, il componente <YouTubeEmbed> esportato da @next/third-parties utilizza lite-youtube-embed che, se dimostrato in un confronto "Hello, World" Next.js, si carica molto più velocemente.

GIF che mostra il confronto del caricamento della pagina tra il componente Incorpora di YouTube e un normale iframe di YouTube
WebPageTest (4G mobile - Virginia USA)

Allo stesso modo, per Google Maps includiamo loading="lazy" come attributo predefinito per l'incorporamento per garantire che la mappa venga caricata solo quando si trova a una determinata distanza dall'area visibile. Può sembrare un attributo ovvio da includere, soprattutto perché la documentazione di Google Maps lo include nello snippet di codice di esempio, ma solo il 45% dei siti Next.js che incorporano Google Maps utilizza loading="lazy".

Esecuzione di script di terze parti in un web worker

Una tecnica avanzata che stiamo esaminando in @next/third-parties consiste nel semplificare il trasferimento degli script di terze parti ai web worker. Popolare da librerie come Partytown, può ridurre sostanzialmente l'impatto degli script di terze parti sulle prestazioni delle pagine, spostandoli completamente dal thread principale.

La seguente GIF animata mostra le variazioni nelle attività lunghe e nel tempo di blocco dei thread principale quando si applicano strategie <Script> diverse a un contenitore GTM in un sito Next.js. Tieni presente che, anche se il passaggio da un'opzione di strategia all'altra ritarda solo l'esecuzione degli script, il loro trasferimento a un web worker elimina completamente il tempo trascorso nel thread principale.

GIF che mostra le differenze nel tempo di blocco dei thread principali per le diverse strategie di script
WebPageTest (4G mobile - Virginia USA)

In questo particolare esempio, lo spostamento dell'esecuzione del contenitore GTM e dei relativi script dei tag associati a un web worker ha ridotto la metrica TBT del 92%.

Vale la pena notare che, se non gestita attentamente, questa tecnica può interrompere in silenzio molti script di terze parti, rendendo il debug difficile. Nei prossimi mesi, verificheremo se i componenti di terze parti offerti da @next/third-parties funzionano correttamente quando vengono eseguiti in un web worker. In tal caso, ci impegneremo per offrire agli sviluppatori un modo semplice e facoltativo per utilizzare questa tecnica.

Passaggi successivi

Durante il processo di sviluppo di questo pacchetto, è emerso che era necessario centralizzare i suggerimenti di caricamento di terze parti in modo che anche altri framework potessero trarre vantaggio dalle stesse tecniche sottostanti utilizzate. Questo ci ha portato a creare Capitale di terze parti, una libreria che utilizza JSON per descrivere le tecniche di caricamento di terze parti, che al momento costituiscono la base di @next/third-parties.

Nei passaggi successivi, continueremo a concentrarci sul miglioramento dei componenti forniti per Next.js e ad ampliare i nostri sforzi per includere utilità simili in altri framework e piattaforme CMS popolari. Attualmente collaboriamo con i gestori di manutenzione di Nuxt e prevediamo di rilasciare utilità di terze parti simili su misura per il loro ecosistema nel prossimo futuro.

Se una delle terze parti che utilizzi nell'app Next.js è supportata da @next/third-parties, installa il pacchetto e prova. Ci piacerebbe ricevere il tuo feedback su GitHub.