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, abbiamo sviluppato le sue 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 libreria @next/third-parties, nonché un'idea delle iniziative future previste 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 tassi di superamento Interaction to Next Paint (INP) e Largest Contentful Paint (LCP).
La correlazione osservata in questo grafico non implica una relazione di causa ed effetto. Tuttavia, gli esperimenti locali forniscono ulteriori prove del fatto che gli script di terze parti influiscono in modo significativo sul rendimento delle pagine. Ad esempio, il grafico riportato di seguito confronta 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 di Next.js.
La documentazione di WebPageTest fornisce dettagli su come vengono misurati questi tempi. A prima vista, è chiaro che tutte queste metriche di laboratorio sono interessate dal contenitore GTM. Ad esempio, il tempo di blocco totale (TBT), un utile proxy di laboratorio che approssima l'INP, ha registrato un aumento di quasi 20 volte.
Componente Script
Quando abbiamo rilasciato il componente <Script>
in Next.js, ci siamo assicurati di introdurlo tramite un'API facile da usare che somiglia molto all'elemento <script>
tradizionale. Utilizzandolo, gli sviluppatori possono collocare uno script di terze parti in qualsiasi
componente della loro 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, inclusi siti popolari come
Patreon, Target e
Notion, utilizzano il componente <Script>
. Nonostante la sua
efficacia, alcuni sviluppatori hanno sollevato dubbi in merito ai seguenti aspetti:
- Dove posizionare il componente
<Script>
in un'app Next.js rispettando le varie istruzioni di installazione dei diversi provider di terze parti (esperienza per gli sviluppatori). - Qual è la strategia di caricamento più ottimale da utilizzare per diversi script di terze parti (esperienza utente).
Per risolvere entrambi i problemi, abbiamo lanciato @next/third-parties
, una biblioteca specializzata che offre un insieme di componenti e utilità ottimizzati personalizzati per terze parti di uso comune.
Esperienza degli sviluppatori: gestione semplificata delle librerie di terze parti
Molti script di terze parti vengono utilizzati in una percentuale significativa dei siti Next.js; Google Tag Manager è il più popolare ed è usato 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 proprio 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 elementi incorporati. Ad esempio, gli incorporamenti di Google Maps e YouTube
vengono utilizzati rispettivamente nell'8%
e nel
4%
dei siti web Next.js. Inoltre, abbiamo fornito dei componenti per renderli
più semplici da caricare.
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: caricamento più rapido delle librerie di terze parti
In un mondo perfetto, ogni libreria di terze parti ampiamente utilizzata sarebbe completamente ottimizzata, rendendo superflue eventuali astrazioni che ne migliorano il rendimento. Tuttavia, finché non sarà realtà, potremo cercare di migliorare l'esperienza utente quando viene integrata tramite framework popolari come Next.js. Possiamo sperimentare diverse tecniche di caricamento, assicurarci che gli script vengano sequenziati nel modo corretto e infine condividere il nostro feedback con provider di terze parti per incoraggiare le modifiche upstream.
Prendiamo ad esempio gli embed di YouTube. Alcune implementazioni alternative hanno un rendimento molto migliore rispetto all'embed nativo. Attualmente, il componente <YouTubeEmbed>
esportato da @next/third-parties
utilizza lite-youtube-embed che, se dimostrato in un confronto di Next.js intitolato "Hello World", si carica più rapidamente.
Analogamente, per Google Maps includiamo loading="lazy"
come attributo predefinito per l'embed per assicurarci che la mappa venga caricata solo quando si trova a una certa distanza dall'area visibile. Potrebbe sembrare un attributo ovvio da includere, soprattutto poiché 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 worker web
Una tecnica avanzata che stiamo esplorando in @next/third-parties
è semplificare il trasferimento degli script di terze parti a un web worker. Reso popolare da librerie come Partytown, questo approccio può ridurre notevolmente l'impatto degli script di terze parti sul rendimento della pagina riallocandoli completamente dal thread principale.
La seguente GIF animata mostra le variazioni nel tempo di blocco delle attività lunghe e del thread principale quando vengono applicate strategie <Script>
diverse a un contenitore GTM all'interno di un sito Next.js. Tieni presente che, sebbene il passaggio da un'opzione di strategia all'altra solo ritardi i tempi di esecuzione di questi script, il loro trasferimento a un web worker elimina completamente il tempo che trascorrono nel thread principale.
In questo esempio specifico, lo spostamento dell'esecuzione del contenitore GTM e degli script dei tag associati in un web worker ha ridotto il TBT del 92%.
Vale la pena notare che, se non gestita con attenzione, questa tecnica può interrompere silenziosamente molti script di terze parti, rendendo difficile il debug. Nei prossimi
mesi, convalideremo se eventuali componenti di terze parti offerti da
@next/third-parties
funzionano correttamente quando vengono eseguiti in un web worker. In questo caso, ci adopereremo per fornire agli sviluppatori un modo semplice e facoltativo per utilizzare questa tecnica.
Passaggi successivi
Durante il processo di sviluppo del 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 sviluppare Third Party
Capital, una libreria che utilizza JSON per descrivere le tecniche di caricamento di terze parti, che attualmente costituisce la base di @next/third-parties
.
Come passaggio successivo, continueremo a concentrarci sul miglioramento dei componenti forniti per Next.js e a impegnarci per includere utilità simili in altri framework e piattaforme CMS popolari. Al momento collaboriamo con i manutentori di Nuxt e prevediamo di rilasciare nel prossimo futuro utilità di terze parti simili personalizzate per il loro ecosistema.
Se una delle terze parti che utilizzi nella tua app Next.js è supportata da
@next/third-parties
,
installa il pacchetto
e provalo. Ci farebbe piacere ricevere il tuo feedback su
GitHub.