Gli script di terze parti influiscono sul rendimento, perciò è importante controllarli regolarmente e utilizzare tecniche efficienti per il caricamento. Questo codelab mostra come ottimizzare il caricamento delle risorse di terze parti. Sono trattate le seguenti tecniche:
Rimandare il caricamento dello script
Caricamento lento delle risorse non critiche
Preconnessione alle origini richieste
L'app di esempio inclusa presenta una semplice pagina web con tre funzionalità provenienti da origini di terze parti:
Un video incorporato
Una libreria di visualizzazione dei dati per il rendering di un grafico a linee
Un widget di condivisione sui social media
Inizierai misurando il rendimento dell'app e poi applichi ogni tecnica per migliorare diversi aspetti del rendimento dell'app.
Misurare le prestazioni
Innanzitutto, apri l'app di esempio nella visualizzazione a schermo intero:
- Fai clic su Remix per modificare per rendere il progetto modificabile.
- Per visualizzare l'anteprima del sito, premi Visualizza app, quindi premi A schermo intero .
Esegui un controllo del rendimento di Lighthouse sulla pagina per stabilire il rendimento di riferimento:
- Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
- Fai clic sulla scheda Lighthouse.
- Fai clic su Dispositivo mobile.
- Seleziona la casella di controllo Prestazioni. Puoi deselezionare le altre caselle di controllo nella sezione Controlli.
- Fai clic su 3G veloce simulato, rallentamento CPU 4x.
- Seleziona la casella di controllo Libera spazio di archiviazione.
- 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 elevato e che Lighthouse suggerisce due opportunità di indagine: Elimina le risorse che bloccano il rendering e Esegui la preconnessione alle origini richieste. Anche se tutte le metriche sono verdi, le ottimizzazioni produrranno comunque miglioramenti.
Rimandare JavaScript di terze parti
Il controllo Elimina le risorse che bloccano il rendering ha rilevato che puoi risparmiare tempo posticipando uno script proveniente da d3js.org:
D3.js è una libreria JavaScript per la creazione di visualizzazioni dei dati. Il file script.js
nell'app di esempio utilizza le funzioni di utilità D3 per creare il grafico a linee SVG e aggiungerlo alla pagina. L'ordine delle operazioni è importante: script.js
deve essere eseguito dopo l'analisi del documento e il caricamento della libreria D3, motivo per cui è incluso subito prima del tag di chiusura </body>
in index.html
.
Tuttavia, lo script D3 è incluso nel <head>
della pagina, il che blocca l'analisi del resto del documento:
Due attributi magici possono sbloccare il parser se vengono aggiunti al tag script:
async
garantisce che gli script vengano scaricati in background ed eseguiti alla prima occasione al termine del download.defer
garantisce che i download degli script avvengano in background e che vengano eseguiti dopo il completamento dell'analisi.
Poiché questo grafico non è molto importante per la pagina complessiva e molto probabilmente sarà sotto la piega, utilizza defer
per assicurarti che non ci siano blocchi del parser.
Passaggio 1: carica lo script in modo asincrono con l'attributo defer
Nella riga 17 in 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 è differito, script.js
verrà eseguito prima che D3 sia pronto, generando un errore.
Gli script con l'attributo defer
vengono eseguiti nell'ordine in cui sono stati specificati. Per assicurarti che script.js
venga eseguito dopo che D3 è pronto, aggiungi defer
e spostalo fino al <head>
del documento, subito dopo l'elemento <script>
di D3. Ora non blocca più l'analizzatore e il download inizia prima.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
Carica risorse di terze parti tramite caricamento lento
Tutte le risorse che si trovano below the fold sono ottime candidate per il caricamento lento.
L'app di esempio ha un video di YouTube incorporato in un iframe. Per controllare quante richieste vengono inviate dalla pagina e quali provengono dall'iframe di YouTube incorporato:
- Per visualizzare l'anteprima del sito, premi Visualizza app, quindi premi A schermo intero .
- Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
- Fai clic sulla scheda Rete.
- Seleziona la casella di controllo Disattiva cache.
- Seleziona 3G veloce nel menu a discesa Ritardo.
- Ricarica la pagina.
Il riquadro Rete indica che la pagina ha effettuato un totale di 28 richieste e ha trasferito quasi 1 MB di risorse compresse.
Per identificare le richieste effettuate da iframe
di YouTube, cerca l'ID video 6lfaiXM6waw
nella colonna Autore. Per raggruppare tutte le richieste per dominio:
Nel riquadro Rete, fai clic con il tasto destro del mouse sul titolo di una colonna.
Nel menu a discesa, seleziona la colonna Domains (Domini).
Per ordinare le richieste per dominio, fai clic sul titolo della colonna Domains (Domini).
Il nuovo ordinamento rivela che ci sono richieste aggiuntive ai domini Google. In totale, l'iframe di YouTube effettua 14 richieste per script, fogli di stile, immagini e caratteri. Tuttavia, a meno che gli utenti non spostino lo scorrimento verso il basso per riprodurre il video, non hanno davvero bisogno di tutte queste risorse.
Se aspetti di caricare il video tramite il caricamento differito finché 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 lazy è utilizzare Intersection Observer, un'API del 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 differito dell'iframe del video, devi prima impedire il caricamento nel modo consueto. A tal fine, 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 dati che ti consente di memorizzare informazioni aggiuntive sugli elementi HTML standard. Un attributo dati può avere qualsiasi nome, purché inizi con "data-".
Un iframe senza src
non viene caricato.
Passaggio 2: utilizza Intersection Observer per il caricamento differito del video
Per caricare il video quando un utente arriva a quel punto, devi sapere quando ciò accade. È qui che entra in gioco l'API Intersection Observer. L'API Intersection Observer ti consente di registrare una funzione di callback che viene eseguita ogni volta che un elemento che vuoi monitorare 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 assegna un nome al file.
- 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 passagli una funzione di callback da eseguire:
// create a new Intersection Observer
let observer = new IntersectionObserver(callback);
Ora indica a observer
un elemento target da guardare (in questo caso l'iframe del 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 proprietà che descrivono le sue dimensioni, la sua posizione, il momento in cui è entrato nel viewport 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);
});
});
- Per visualizzare l'anteprima del sito, premi Visualizza app, quindi premi A schermo intero .
- Premi "Control+Maiusc+J" (o "Comando+Opzione+J" su Mac) per aprire DevTools.
- Fai clic sulla scheda Console.
Prova a scorrere verso l'alto e verso il basso. Dovresti vedere il valore di isIntersecting
cambiare 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 da data-src
dell'elemento iframe
e lo imposta come attributo src
dell'elemento iframe
. Questa sostituzione attiva il caricamento del video. Una volta caricato il video, chiama il metodo unobserve
su observer
per interrompere la visione 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 indica che la pagina ha effettuato 14 richieste e solo 260 KB. È un miglioramento significativo.
Ora scorri verso il basso nella pagina e tieni d'occhio il riquadro Rete. Quando arrivi al video, dovresti vedere che la pagina attiva richieste aggiuntive.
Preconnettiti alle origini richieste
Hai posticipato il codice JavaScript non critico e hai caricato le richieste di YouTube in modo lazy, quindi è arrivato 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 della risorsa. Questo attributo è ideale per le origini che forniscono le risorse di cui hai la certezza che la pagina abbia bisogno.
Il controllo Lighthouse eseguito nel primo passaggio suggerito in Eseguire la preconnessione alle origini richieste indica che puoi risparmiare circa 400 ms stabilendo connessioni anticipate a staticxx.facebook.com e youtube.com:
Poiché il video di YouTube ora viene caricato in modo lazy, rimane solo staticxx.facebook.com, la sorgente del widget di condivisione sui social media. Per stabilire una connessione anticipata a questo dominio, è sufficiente aggiungere un tag <link>
al <head>
del documento:
<link rel="preconnect" href="https://staticxx.facebook.com">
Rivalutare il rendimento
Ecco lo stato della pagina dopo l'ottimizzazione. Segui i passaggi descritti nella sezione Misurare il rendimento del codelab per eseguire un altro audit Lighthouse.