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

Scopri 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

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 è dotato di best practice e valori predefiniti per aiutare gli sviluppatori a introdurre script di terze parti nelle loro applicazioni, risolvendo al contempo potenziali problemi di prestazioni.

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 creator di questi script in genere non hanno alcun incentivo a considerare l'impatto sul rendimento del sito web di destinazione. 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 dà la priorità agli script in base alla loro posizione nel documento, il che potrebbe ritardare la rilevazione 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 nel thread principale. Lighthouse dispone di due controlli per segnalare gli script che bloccano il rendering o il thread principale.

Controlli di Lighthouse per eliminare le risorse di blocco della visualizzazione 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 le risorse non critiche non blocchino le risorse critiche.

Sebbene esistano best practice per ridurre l'impatto delle terze parti, non tutti potrebbero sapere 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 molti componenti di terze parti può variare a seconda che venga utilizzato un determinato framework o una determinata libreria UI.
  • Vengono introdotte spesso nuove librerie di terze parti.
  • I requisiti aziendali variabili relativi alla stessa terza parte rendono difficile per gli sviluppatori standardizzarne l'utilizzo.

L'attenzione di Aurora sugli script di terze parti

La collaborazione di Aurora con framework e strumenti web open source ha lo scopo di fornire impostazioni predefinite solide e strumenti con opinioni per aiutare gli sviluppatori a migliorare aspetti dell'esperienza utente come prestazioni, accessibilità, sicurezza e idoneità per il mobile. Nel 2021 ci siamo concentrati sull'aiutare gli stack di framework a migliorare l'esperienza utente e le metriche Core Web Vitals.

Uno dei passaggi più significativi per raggiungere il nostro obiettivo di migliorare il rendimento del framework è stato studiare la sequenza di caricamento ideale degli script di terze parti in Next.js. Framework come Next.js sono in una posizione unica per fornire impostazioni predefinite e funzionalità utili che aiutano gli sviluppatori a caricare in modo efficiente le risorse, incluse quelle di terze parti. Abbiamo studiato dati approfonditi di HTTP Archive e Lighthouse per scoprire quali terze parti bloccano maggiormente il rendering in diversi framework.

Per risolvere il problema del blocco del thread principale da parte di script di terze parti 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.

Sequenzare script di terze parti senza un componente del framework

Le linee guida 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'interprete 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, gli script critici possono iniziare a essere scaricati prima.

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

Componente Script di Next.js

Il componente Script di Next.js implementa i metodi precedenti per la sequenziazione degli script e fornisce un modello per consentire agli sviluppatori di definire la propria strategia di caricamento. Una volta specificata la strategia adatta, verrà caricata in modo ottimale senza bloccare altre risorse critiche.

Il componente Script si basa sul tag HTML <script> e offre un'opzione per impostare la priorità di caricamento degli 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 assicura che questi script vengano iniettati nel codice HTML iniziale sul server ed eseguiti prima di altri script JavaScript auto-raggruppati. La gestione del consenso, gli script di rilevamento dei bot o le librerie di supporto necessarie per visualizzare contenuti critici sono buoni candidati per questa strategia.

  2. afterInteractive: è la strategia predefinita applicata ed è equivalente 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 inietta 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 posticipati da Next.js, fornendo così un'impostazione predefinita efficace.

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

Gli sviluppatori possono indicare a Next.js in che modo 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 sequenza di caricamento migliore.

Utilizzando il componente Script, gli sviluppatori possono inserire uno script di terze parti in qualsiasi punto dell'applicazione per il caricamento tardivo di terze parti e a livello di documento per gli script critici. Ciò implica che il componente Script può essere collocato nello stesso spazio del componente che utilizza lo script. Dopo l'idratazione, lo script verrà inserito nell'elemento head del documento visualizzato inizialmente o nella parte inferiore del corpo, a seconda della strategia utilizzata.

Misurare l'impatto

Abbiamo utilizzato i modelli per l'app di commercio e il blog di avvio 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 embed dei social media sono state incluse nelle pagine di queste app inizialmente 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 commercio Next.js

Per la demo sono stati aggiunti al modello di app di commercio gli script di terze parti indicati di seguito.

Prima Dopo
Google Tag Manager con async Componente dello script con strategia = afterInteractive per entrambi gli script
Pulsante Segui di Twitter senza asincrono o posticipazione
Configurazione di script e componenti dello script per la demo 1 con 2 script.

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

Confronto di una striscia di pellicola che mostra il miglioramento del LCP

Script di terze parti in un blog Next.js

All'app del blog di esempio sono stati aggiunti script di terze parti come indicato di seguito.

Prima Dopo
Google Tag Manager con async Componente script con strategia = lazyonload per ciascuno dei quattro script
Pulsante Segui di Twitter con asincrono
Pulsante di iscrizione a YouTube senza asincrono o posticipazione
Pulsante Segui di LinkedIn senza asincrono o posticipazione
Configurazione di script e componenti dello script per la demo 2 con 4 script.
Video che mostra l&#39;avanzamento del caricamento della pagina di indice con e senza il componente Script. Il componente Script consente di migliorare il tempo di caricamento della prima pagina 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 offrano un controllo significativo sugli script che bloccano il rendering, stiamo anche valutando altre opzioni che potrebbero aumentare l'utilità del componente Script.

Utilizzare i web worker

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

Con l'attuale implementazione del componente script di Next.js, ti consigliamo di posticipare questi script nel thread principale impostando la strategia su afterInteractive o lazyOnload. In futuro, prevediamo 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 entusiasmo i commenti degli sviluppatori su questo RFC.

Ridurre al minimo il CLS

Gli elementi incorporati di terze parti, come annunci, video o feed di social media, possono causare cambiamenti nel layout quando vengono caricati in modo lazy. Ciò influisce sull'esperienza utente e sulla metrica Variazione layout cumulativa (CLS) della pagina. Il CLS può essere ridotto al minimo specificando le dimensioni del contenitore in cui verrà caricato l'embed.

Il componente Script può essere utilizzato per caricare elementi incorporati che possono causare variazioni del layout. Stiamo valutando la possibilità di ampliarlo per fornire opzioni di configurazione che aiutino a ridurre il CLS. 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 in genere fisse. Questi possono essere ulteriormente incapsulati in singoli componenti wrapper per ogni tipo di script. Agli sviluppatori sarà disponibile solo un insieme minimo di attributi specifici dell'applicazione (ad esempio l'ID monitoraggio). I componenti wrapper aiutano gli sviluppatori a:

  1. Consentendo loro di includere più facilmente i tag script più utilizzati.
  2. Garantisce che il framework utilizzi la strategia più ottimale.

Conclusione

Gli script di terze parti vengono solitamente creati per includere funzionalità specifiche nel sito web di destinazione. Per ridurre l'impatto degli script non critici, ti consigliamo di differirli, come fa il componente Script di Next.js 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 prendere in considerazione la creazione di queste funzionalità in altri framework. Stiamo esplorando attivamente la possibilità di implementare un componente simile con il team di Nuxt.js. In base al feedback, ci auguriamo anche di migliorare ulteriormente il componente Script per coprire altri casi d'uso.

Riconoscimenti

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