Ottimizzazione del caricamento degli script di terze parti in Next.js

Comprendi la visione alla base del componente Script di Next.js, che fornisce una soluzione integrata per ottimizzare il caricamento degli script di terze parti.

Leena Sohoni
Leena Sohoni
Houssein Djirdeh
Houssein Djirdeh

Circa il 45% delle richieste provenienti da siti web pubblicati su dispositivi mobili e computer sono richieste di terze parti, di cui il 33% sono script. Le dimensioni, la latenza e il caricamento degli script di terze parti possono influire notevolmente sulle prestazioni di un sito. Il componente Script di Next.js include best practice e valori predefiniti integrati per aiutare gli sviluppatori a introdurre script di terze parti nelle loro applicazioni, risolvendo al contempo i potenziali problemi di prestazioni in modo immediato.

Script di terze parti e il loro impatto sul rendimento

Gli script di terze parti consentono agli sviluppatori web di sfruttare le soluzioni esistenti per implementare funzionalità comuni e ridurre i tempi di sviluppo. Tuttavia, i creatori di questi script in genere non hanno alcun incentivo a considerare l'impatto sul rendimento del sito web che li utilizza. Questi script sono anche una scatola nera per gli sviluppatori che li utilizzano.

Gli script rappresentano un numero significativo di byte di terze parti scaricati dai siti web in diverse categorie di richieste di terze parti. Per impostazione predefinita, il browser assegna la priorità agli script in base alla loro posizione nel documento, il che potrebbe ritardare il rilevamento o l'esecuzione di script fondamentali per l'esperienza utente.

Le librerie di terze parti necessarie per il layout devono essere caricate in anticipo per eseguire il rendering della pagina. Le terze parti non necessarie per il rendering iniziale devono essere differite in modo da non bloccare altre elaborazioni sul thread principale. Lighthouse prevede due controlli per segnalare gli script che bloccano il rendering o il thread principale.

Controlli di Lighthouse per Eliminare le risorse che bloccano il rendering e Ridurre al minimo l'utilizzo di codice di terze parti

È importante considerare la sequenza di caricamento delle risorse della pagina in modo che le risorse critiche non vengano ritardate e quelle non critiche non blocchino le risorse critiche.

Sebbene esistano best practice per ridurre l'impatto delle terze parti, non tutti sanno come implementarle per ogni terza parte che utilizzano. Questo può essere complicato perché:

  • In media, i siti web utilizzano da 21 a 23 terze parti diverse, inclusi gli script, su dispositivi mobili e computer. L'utilizzo e i consigli possono variare per ciascuno.
  • L'implementazione di molte terze parti può variare a seconda che venga utilizzato un determinato framework o una libreria UI.
  • Le librerie di terze parti più recenti vengono introdotte di frequente.
  • I diversi requisiti aziendali relativi alla stessa terza parte rendono difficile per gli sviluppatori standardizzarne l'utilizzo.

L'attenzione di Aurora sugli script di terze parti

Parte della collaborazione di Aurora con framework e strumenti web open source consiste nel fornire impostazioni predefinite efficaci e strumenti mirati per aiutare gli sviluppatori a migliorare aspetti dell'esperienza utente come prestazioni, accessibilità, sicurezza e idoneità per i dispositivi mobili. Nel 2021, ci siamo concentrati sull'aiutare gli stack di framework a migliorare l'esperienza utente e le metriche di Core Web Vitals.

Uno dei passaggi più significativi per raggiungere il nostro obiettivo di migliorare le prestazioni del framework ha riguardato la ricerca della sequenza di caricamento ideale degli script di terze parti in Next.js. I framework come Next.js sono in una posizione unica per fornire valori predefiniti e funzionalità utili che aiutano gli sviluppatori a caricare in modo efficiente le risorse, incluse quelle di terze parti. Abbiamo studiato i dati completi di HTTP Archive e Lighthouse per scoprire quali terze parti bloccano il rendering maggiormente nei diversi framework.

Per risolvere il problema degli script di terze parti che bloccano il thread principale utilizzati in un'applicazione, abbiamo creato il componente Script. Il componente incapsula le funzionalità di sequenziamento per fornire agli sviluppatori controlli migliori per il caricamento di script di terze parti.

Sequenza di script di terze parti senza un componente del framework

Le indicazioni disponibili per ridurre l'impatto degli script che bloccano il rendering forniscono i seguenti metodi per caricare e sequenziare in modo efficiente gli script di terze parti:

  1. Utilizza l'attributo async o defer con i tag <script> che indicano al browser di caricare script di terze parti non critici senza bloccare l'analizzatore sintattico del documento. Gli script non necessari per il caricamento iniziale della pagina o per la prima interazione dell'utente possono essere considerati non critici.

       <script src="https://example.com/script1.js" defer></script>
       <script src="https://example.com/script2.js" async></script>
    
  2. Stabilisci connessioni anticipate alle origini richieste utilizzando preconnect e dns-prefetch. In questo modo, il download degli script critici può iniziare prima.

       <head>
           <link rel="preconnect" href="http://PreconnThis.com">
           <link rel="dns-prefetch" href="http://PrefetchThis.com">
       </head>
    
  3. Carica lentamente le risorse e gli elementi incorporati di terze parti al termine del caricamento dei contenuti della pagina principale o quando l'utente scorre verso il basso fino alla parte della pagina in cui sono inclusi.

Il componente Script di Next.js

Il componente Script di Next.js implementa i metodi descritti sopra per la sequenza degli script e fornisce un modello che gli sviluppatori possono utilizzare per definire la propria strategia di caricamento. Una volta specificata la strategia adatta, verrà caricato in modo ottimale senza bloccare altre risorse critiche.

Il componente Script si basa sul tag HTML <script> e fornisce un'opzione per impostare la priorità di caricamento per gli script di terze parti utilizzando l'attributo strategy.

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

L'attributo strategy può assumere tre valori.

  1. beforeInteractive: questa opzione può essere utilizzata per gli script critici che devono essere eseguiti prima che la pagina diventi interattiva. Next.js garantisce che questi script vengano inseriti nell'HTML iniziale sul server ed eseguiti prima di altri JavaScript con bundle autonomo. La gestione del consenso, gli script di rilevamento dei bot o le librerie di supporto necessarie per il rendering dei contenuti critici sono buoni candidati per questa strategia.

  2. afterInteractive: questa è la strategia predefinita applicata ed equivale al caricamento di uno script con l'attributo defer. Deve essere utilizzato per gli script che il browser può eseguire dopo che la pagina è interattiva, ad esempio gli script di analisi. Next.js inserisce questi script lato client, che vengono eseguiti dopo l'idratazione della pagina. Pertanto, se non diversamente specificato, tutti gli script di terze parti definiti utilizzando il componente Script vengono differiti da Next.js, fornendo così un'impostazione predefinita efficace.

  3. lazyOnload: questa opzione può essere utilizzata per il caricamento lento di script con priorità bassa quando il browser è inattivo. La funzionalità fornita da questi script non è necessaria immediatamente dopo che la pagina diventa interattiva, ad esempio i plug-in di chat o social media.

Gli sviluppatori possono indicare a Next.js come la loro applicazione utilizza uno script specificando la strategia. In questo modo, il framework può applicare ottimizzazioni e best practice per caricare lo script, garantendo al contempo la migliore sequenza di caricamento.

Utilizzando il componente Script, gli sviluppatori possono inserire uno script di terze parti in qualsiasi punto dell'applicazione per le terze parti con caricamento ritardato e a livello di documento per gli script critici. Ciò implica che il componente Script potrebbe essere collocato insieme al componente che utilizza lo script. Dopo l'idratazione, lo script verrà inserito nell'intestazione del documento visualizzato inizialmente o in fondo al corpo, a seconda della strategia utilizzata.

Misurazione dell'impatto

Abbiamo utilizzato i modelli per l'app di e-commerce e il blog iniziale di Next.js per creare due app demo che hanno contribuito a misurare l'impatto dell'inclusione di script di terze parti. Le terze parti di uso comune per Google Tag Manager e gli incorporamenti dei social media sono state incluse nelle pagine di queste app prima direttamente e poi tramite il componente Script. Abbiamo poi confrontato il rendimento di queste pagine su WebPageTest.

Script di terze parti in un'app di e-commerce Next.js

Gli script di terze parti sono stati aggiunti al modello di app di e-commerce per la demo, come mostrato di seguito.

Prima Dopo
Google Tag Manager con async Componente script con strategy = afterInteractive per entrambi gli script
Pulsante Segui di Twitter senza async o defer
Configurazione di Script e Script Component per la demo 1 con 2 script.

Il seguente confronto mostra l'avanzamento visivo per entrambe le versioni dello starter kit di e-commerce Next.js. Come puoi vedere, l'LCP si verifica quasi 1 secondo prima con il componente Script attivato con la strategia di caricamento corretta.

Confronto di sequenze di immagini che mostra un miglioramento dell'LCP

Script di terze parti in un blog Next.js

Gli script di terze parti sono stati aggiunti all'app del blog demo come indicato di seguito.

Prima Dopo
Google Tag Manager con async Componente script con strategy = lazyonload per ciascuno dei quattro script
Pulsante Segui di Twitter con async
Pulsante Iscriviti di YouTube senza async o defer
Pulsante Segui di LinkedIn senza async o defer
Configurazione di Script e Script Component per la demo 2 con 4 script.
Video che mostra l'avanzamento del caricamento della pagina indice con e senza il componente Script. Con il componente Script, il valore FCP è migliorato di 0,5 secondi.

Come mostrato nel video, il First Contentful Paint (FCP) si verifica a 0,9 secondi nella pagina senza il componente Script e a 0,4 secondi con il componente Script.

Novità per il componente Script

Sebbene le opzioni di strategia per afterInteractive e lazyOnload forniscano un controllo significativo sugli script che bloccano il rendering, stiamo anche esplorando altre opzioni che aumenterebbero l'utilità del componente Script.

Utilizzo dei web worker

I web worker possono essere utilizzati per eseguire script indipendenti su thread in background, liberando il thread principale per gestire l'elaborazione delle attività dell'interfaccia utente e migliorare le prestazioni. I web worker sono più adatti per l'offload dell'elaborazione JavaScript, anziché del lavoro sulla UI, dal thread principale. Gli script utilizzati per l'assistenza clienti o il marketing, che in genere non interagiscono con la UI, potrebbero essere buoni candidati per l'esecuzione su un thread in background. È possibile utilizzare una libreria di terze parti leggera, PartyTown, per isolare questi script in un web worker.

Con l'implementazione attuale del componente script Next.js, ti consigliamo di posticipare questi script nel thread principale impostando la strategia su afterInteractive o lazyOnload. In futuro, proponiamo di introdurre una nuova opzione di strategia, 'worker', che consentirà a Next.js di utilizzare PartyTown o una soluzione personalizzata per eseguire script sui web worker. Accogliamo con favore i commenti degli sviluppatori su questa RFC.

Riduzione al minimo del CLS

Gli elementi incorporati di terze parti, come annunci, video o feed di social media, possono causare variazioni del layout quando vengono caricati con il caricamento lento. Ciò influisce sull'esperienza utente e sulla metrica Cumulative Layout Shift (CLS) della pagina. Il CLS può essere ridotto al minimo specificando le dimensioni del contenitore in cui verrà caricato l'incorporamento.

Il componente Script può essere utilizzato per caricare elementi incorporati che possono causare variazioni del layout. Stiamo valutando la possibilità di migliorarlo per fornire opzioni di configurazione che contribuiranno a ridurre il CLS. Questo potrebbe essere reso disponibile all'interno del componente Script stesso o come componente aggiuntivo.

Componenti wrapper

La sintassi e la strategia di caricamento per l'inclusione di script di terze parti popolari come Google Analytics o Google Tag Manager (GTM) sono solitamente fisse. Questi possono essere ulteriormente incapsulati in singoli componenti wrapper per ogni tipo di script. Solo un insieme minimo di attributi specifici dell'applicazione (come l'ID monitoraggio) sarà disponibile per gli sviluppatori. I componenti wrapper aiuteranno gli sviluppatori:

  1. In questo modo, è più facile includere i tag di script più diffusi.
  2. In questo modo, il framework utilizza la strategia più ottimale in background.

Conclusione

Gli script di terze parti vengono solitamente creati per includere funzionalità specifiche nel sito web che li utilizza. Per ridurre l'impatto degli script non critici, ti consigliamo di posticiparli, cosa che il componente Script di Next.js fa per impostazione predefinita. Gli sviluppatori hanno la certezza che gli script inclusi non ritarderanno le funzionalità critiche, a meno che non applichino esplicitamente la strategia beforeInteractive. Come per il componente Script di Next.js, gli sviluppatori di framework possono anche valutare la possibilità di creare queste funzionalità in altri framework. Stiamo valutando attivamente l'inserimento di un componente simile con il team di Nuxt.js. In base al feedback, speriamo anche di migliorare ulteriormente il componente Script per coprire altri casi d'uso.

Riconoscimenti

Ringraziamo Kara Erickson, Janicklas Ralph, Katie Hempenius, Philip Walton, Jeremy Wagner e Addy Osmani per il loro feedback su questo post.