Ottimizza JavaScript di terze parti

Milica Mihajlija
Milica Mihajlija

Gli script di terze parti influiscono sul rendimento, motivo per cui è importante verificarli regolarmente e utilizzare tecniche efficaci per caricarli. Questo codelab mostra come ottimizzare il caricamento delle risorse di terze parti. Verranno trattate le seguenti tecniche:

  • Rinvio del caricamento dello script

  • Caricamento lento delle risorse non critiche

  • Preconnessione alle origini richieste

L'app di esempio inclusa presenta una pagina web semplice con tre funzionalità provenienti da fonti di terze parti:

  • Un video incorporato

  • Una libreria di visualizzazione dati per il rendering di un grafico a linee.

  • Un widget per la condivisione sui social media

Screenshot della pagina con le risorse di terze parti evidenziate.
Risorse di terze parti nell'app di esempio.

Inizierai misurando il rendimento dell'app e poi applicherai ciascuna tecnica per migliorare aspetti diversi del rendimento dell'app.

Misurare il rendimento

Per prima cosa, apri l'app di esempio in visualizzazione a schermo intero:

  1. Fai clic su Remix per modificare per rendere il progetto modificabile.
  2. Per visualizzare l'anteprima del sito, premi Visualizza app, quindi Schermo intero schermo intero.

Esegui un controllo delle prestazioni di Lighthouse sulla pagina per stabilire le prestazioni di base:

  1. Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
  2. Fai clic sulla scheda Lighthouse.
  3. Fai clic su Dispositivo mobile.
  4. Seleziona la casella di controllo Rendimento. Puoi deselezionare le altre caselle di controllo nella sezione Controlli.
  5. Fai clic su Simulato Fast 3G, 4x CPU Slowdown.
  6. Seleziona la casella di controllo Cancella dati archiviati.
  7. Fai clic su Esegui controlli.

Quando esegui un controllo sul tuo computer, i risultati esatti possono variare, ma dovresti notare che il tempo di First Contentful Paint (FCP) è piuttosto lungo e che Lighthouse suggerisce due opportunità per esaminare: Eliminare le risorse che bloccano la visualizzazione e Preconnettersi alle origini richieste. Anche se le metriche sono tutte in verde, le ottimizzazioni produrranno comunque miglioramenti.

Screenshot del controllo Lighthouse che mostra un FCP di 2,4 secondi e due opportunità: elimina le risorse che bloccano la visualizzazione e precollegati alle origini richieste.

Rimanda JavaScript di terze parti

Il controllo Elimina le risorse che bloccano la visualizzazione ha individuato che è possibile risparmiare tempo rinviando uno script proveniente da d3js.org:

Screenshot del controllo Elimina le risorse che bloccano il rendering con lo script d3.v3.min.js evidenziato.

D3.js è una libreria JavaScript per la creazione di visualizzazioni di dati. Il file script.js nell'app di esempio utilizza le funzioni dell'utilità D3 per creare il grafico a linee SVG e aggiungerlo alla pagina. L'ordine delle operazioni in questo caso è importante: script.js deve essere eseguito dopo l'analisi del documento e il caricamento della libreria D3, per questo è stato incluso immediatamente prima del tag </body> di chiusura in index.html.

Tuttavia, lo script D3 è incluso nel <head> della pagina, il che blocca l'analisi del resto del documento:

Screenshot di index.html con il tag script evidenziato nell&#39;intestazione.

Due attributi magici possono sbloccare il parser quando vengono aggiunti al tag script:

  • async assicura che gli script vengano scaricati in background ed eseguiti alla prima opportunità al termine del download.

  • defer assicura che gli script vengano scaricati in background ed eseguiti al termine dell'analisi.

Poiché questo grafico non è fondamentale per la pagina nel complesso e molto probabilmente si troverà below the fold, usa defer per assicurarti che non ci siano blocchi dell'analizzatore sintattico.

Passaggio 1: carica lo script in modo asincrono con l'attributo defer

Alla riga 17 di index.html, aggiungi l'attributo defer all'elemento <script>:

<script src="https://d3js.org/d3.v3.min.js" defer></script>

Passaggio 2: assicurati che l'ordine delle operazioni sia corretto

Ora che D3 viene differito, script.js verrà eseguito prima che D3 sia pronto, causando un errore.

Gli script con l'attributo defer vengono eseguiti nell'ordine in cui sono stati specificati. Per assicurarti che l'script.js venga eseguita dopo che D3 è pronto, aggiungi defer e spostalo fino al <head> del documento, subito dopo l'elemento <script> D3. Ora non blocca più il parser e il download inizia prima.

<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>

Caricamento lento delle risorse di terze parti

Tutte le risorse below the fold sono ideali per il caricamento lento.

L'app di esempio ha un video di YouTube incorporato in un iframe. Per scoprire quante richieste fa la pagina e quali provengono dall'iframe di YouTube incorporato:

  1. Per visualizzare l'anteprima del sito, premi Visualizza app, quindi Schermo intero schermo intero.
  2. Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
  3. Fai clic sulla scheda Rete.
  4. Seleziona la casella di controllo Disabilita cache.
  5. Seleziona 3G veloce nel menu a discesa Riduzione.
  6. Ricarica la pagina.

Screenshot del riquadro Network (Rete) di DevTools.

Il riquadro Rete mostra che la pagina ha effettuato un totale di 28 richieste e ha trasferito quasi 1 MB di risorse compresse.

Per identificare le richieste effettuate dal iframe di YouTube, cerca l'ID video 6lfaiXM6waw nella colonna Iniziatore. Per raggruppare tutte le richieste in base al dominio:

  • Nel riquadro Rete, fai clic con il tasto destro del mouse sul titolo di una colonna.

  • Nel menu a discesa, seleziona la colonna Domini.

  • Per ordinare le richieste in base al dominio, fai clic sul titolo della colonna Domini.

Il nuovo ordinamento rivela la presenza di richieste aggiuntive ai domini Google. In totale, l'iframe di YouTube effettua 14 richieste di script, fogli di stile, immagini e caratteri. Tuttavia, a meno che gli utenti scorrano effettivamente verso il basso per riprodurre il video, non hanno bisogno di tutti questi asset.

Se aspetti il caricamento lento del video fino a quando un utente non scorre fino a quella sezione della pagina, riduci il numero di richieste effettuate inizialmente dalla pagina. Questo approccio consente di salvare i dati degli utenti e di velocizzare il caricamento iniziale.

Un modo per implementare il caricamento lento consiste nell'utilizzare Intersection Observationr, un'API browser che ti avvisa quando un elemento entra o esce dall'area visibile del browser.

Passaggio 1: impedisci il caricamento iniziale del video

Per eseguire il caricamento lento dell'iframe video, devi prima impedirne il caricamento come di consueto. Per farlo, sostituisci l'attributo src con l'attributo data-src per specificare l'URL del video:

<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

data-src è un attributo dei dati che ti consente di memorizzare informazioni aggiuntive sugli elementi HTML standard. Un attributo dei dati può avere un qualsiasi nome, purché inizi con "data-".

Un iframe senza src semplicemente non viene caricato.

Passaggio 2: usa Intersection Observationr per il caricamento lento del video

Per caricare il video quando un utente scorre fino a questo, devi sapere quando succede. È qui che entra in gioco l'API Intersection Observationr. L'API Intersection Observationr consente di registrare una funzione di callback che viene eseguita ogni volta che un elemento di cui vuoi tenere traccia entra o esce dall'area visibile.

Per iniziare, crea un nuovo file e assegnagli il nome lazy-load.js:

  • Fai clic su Nuovo file e assegnagli un nome.
  • Fai clic su Aggiungi questo file.

Aggiungi il tag script all'intestazione del documento:

 <script src="/lazy-load.js" defer></script>

In lazy-load.js, crea un nuovo IntersectionObserver e trasmettigli una funzione di callback da eseguire:

// create a new Intersection Observer
let observer = new IntersectionObserver(callback);

Ora assegna a observer un elemento target da guardare (in questo caso l'iframe video) passandolo come argomento nel metodo observe:

// the element that you want to watch
const element = document.querySelector('iframe');

// register the element with the observe method
observer.observe(element);

callback riceve un elenco di oggetti IntersectionObserverEntry e l'oggetto IntersectionObserver stesso. Ogni voce contiene un elemento target e le relative proprietà che ne descrivono le dimensioni, la posizione, l'ora di accesso all'area visibile e altro ancora. Una delle proprietà di IntersectionObserverEntry è isIntersecting, un valore booleano uguale a true quando l'elemento entra nell'area visibile.

In questo esempio, target è iframe. isIntersecting è uguale a true quando target entra nell'area visibile. Per vedere come funziona, sostituisci callback con la seguente funzione:

let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
    entries.forEach(entry => {
      console.log(entry.target);
      console.log(entry.isIntersecting);
    });
  });
  1. Per visualizzare l'anteprima del sito, premi Visualizza app, quindi Schermo intero schermo intero.
  2. Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
  3. Fai clic sulla scheda Console.

Prova a scorrere verso l'alto e verso il basso. Dovresti vedere il valore della modifica di isIntersecting e l'elemento target registrato nella console.

Per caricare il video quando l'utente scorre fino alla sua posizione, utilizza isIntersecting come condizione per eseguire una funzione loadElement, che recupera il valore dall'elemento data-src dell'elemento iframe e lo imposta come attributo src dell'elemento iframe. Questa sostituzione attiva il caricamento del video. Quindi, una volta caricato il video, chiama il metodo unobserve sull'observer per interrompere la visualizzazione dell'elemento target:

let observer = new IntersectionObserver(function (entries, observer) {
  entries.forEach(entry => {
    console.log(entry.target);
    console.log(entry.isIntersecting);
  });
});
    if (entry.isIntersecting) {
      // do this when the element enters the viewport
      loadElement(entry.target);
      // stop watching
      observer.unobserve(entry.target);
    }
  });
});

function loadElement(element) {
  const src = element.getAttribute('data-src');
  element.src = src;
}

Passaggio 3. Rivaluta il rendimento

Per vedere come sono cambiate le dimensioni e il numero di risorse, apri il riquadro Rete di DevTools e ricarica di nuovo la pagina. Il riquadro Rete mostra che la pagina ha effettuato 14 richieste e solo 260 kB. Si tratta di un miglioramento significativo.

Ora scorri verso il basso nella pagina e tieni d'occhio il riquadro Network (Rete). Quando arrivi al video, dovresti vedere che la pagina attiva richieste aggiuntive.

Preconnetti alle origini richieste

Hai differito il codice JavaScript non critico e il caricamento lento delle richieste di YouTube, quindi ora è il momento di ottimizzare i restanti contenuti di terze parti.

L'aggiunta dell'attributo rel=preconnect a un link indica al browser di stabilire una connessione a un dominio prima che venga effettuata la richiesta per quella risorsa. Questo attributo viene usato al meglio su origini che forniscono risorse di cui hai bisogno per la pagina.

Il controllo di Lighthouse che hai eseguito nel primo passaggio suggerito in Preconnessione alle origini richieste che puoi risparmiare circa 400 ms stabilindo connessioni in anticipo a staticxx.facebook.com e youtube.com:

Preconnettiti al controllo delle origini richiesto con il dominio staticxx.facebook.com evidenziato.

Dal momento che il video di YouTube viene ora caricato tramite caricamento lento, rimane solo staticxx.facebook.com, la fonte del widget di condivisione sui social media. Stabilire una connessione anticipata a questo dominio è semplice quanto aggiungere un tag <link> al <head> del documento:

  <link rel="preconnect" href="https://staticxx.facebook.com">

Rivalutare il rendimento

Questo è lo stato della pagina dopo l'ottimizzazione. Segui i passaggi della sezione Misurare le prestazioni del codelab per eseguire un altro controllo di Lighthouse.

Audit Lighthouse che mostra 1 secondo di FCP e il punteggio delle prestazioni di 99.