Codelab: precarica gli asset critici per migliorare la velocità di caricamento

Houssein Djirdeh
Houssein Djirdeh

In questo codelab, le prestazioni della seguente pagina web vengono migliorate precaricando e precaricando in anticipo alcune risorse:

Screenshot app

Misura

Misura innanzitutto il rendimento del sito web prima di aggiungere eventuali ottimizzazioni.

  • Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi Schermo intero schermo intero.

Esegui il controllo del rendimento di Lighthouse (Lighthouse > Opzioni > Rendimento) sulla versione live del tuo progetto Glitch (vedi anche Scopri le opportunità di miglioramento del rendimento con Lighthouse).

Lighthouse mostra il seguente audit non riuscito per una risorsa recuperata in ritardo:

Lighthouse: controllo Preload key requests
  • Premi "Control+Maiusc+J" (o "Command+Opzione+J" su Mac) per aprire DevTools.
  • Fai clic sulla scheda Rete.
Riquadro Network con risorsa rilevata in ritardo

Il file main.css non viene recuperato da un elemento Link (<link>) inserito nel documento HTML, ma un file JavaScript separato, fetch-css.js, collega l'elemento Link al DOM dopo l'evento window.onLoad. Ciò significa che il file viene recuperato dopo che il browser ha terminato l'analisi e l'esecuzione del file JS. Allo stesso modo, un carattere web (K2D.woff2) specificato all'interno di main.css viene recuperato solo al termine del download del file CSS.

La catena di richieste fondamentali rappresenta l'ordine delle risorse che vengono prioritizzate e recuperate dal browser. Per questa pagina web, al momento l'aspetto è il seguente:

├─┬ / (initial HTML file)
  └── fetch-css.js
    └── main.css
      └── K2D.woff2

Poiché il file CSS si trova al terzo livello della catena di richieste, Lighthouse lo ha identificato come risorsa rilevata in ritardo.

Precaricare le risorse critiche

Il file main.css è una risorsa fondamentale necessaria immediatamente non appena la pagina viene caricata. Per i file importanti come questa risorsa recuperata in un secondo momento nell'applicazione, utilizza un tag di precaricamento dei link per comunicare al browser di scaricarlo prima aggiungendo un elemento Link all'intestazione del documento.

Aggiungi un tag di precaricamento per questa applicazione:

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
</head>

L'attributo as viene utilizzato per identificare il tipo di risorsa recuperata, mentre as="style" viene utilizzato per precaricare i file di fogli di stile.

Ricarica l'applicazione e dai un'occhiata al riquadro Rete in DevTools.

riquadro Network con risorsa precaricata

Nota come il browser recupera il file CSS prima che l'analisi del codice JavaScript responsabile del recupero sia terminata. Con il precaricamento, il browser sa di dover recuperare in modo preventivo la risorsa presupponendo che sia fondamentale per la pagina web.

Se non utilizzato correttamente, il precaricamento può compromettere le prestazioni effettuando richieste non necessarie di risorse che non vengono utilizzate. In questa applicazione, details.css è un altro file CSS che si trova nella radice del progetto, ma viene utilizzato per un /details route separato. Per mostrare un esempio di come il precaricamento può essere utilizzato in modo errato, aggiungi anche un suggerimento di precaricamento per questa risorsa.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Ricarica l'applicazione e dai un'occhiata al riquadro Rete. Viene effettuata una richiesta per recuperare details.css anche se non viene utilizzato dalla pagina web.

Pannello Network con precaricamento non necessario

Chrome mostra un avviso nel riquadro Console quando una risorsa precaricata non viene utilizzata dalla pagina entro pochi secondi dal caricamento.

Avviso di precaricamento nella console

Utilizza questo avviso come indicatore per identificare se hai risorse precaricate che non vengono utilizzate immediatamente dalla tua pagina web. Ora puoi rimuovere il link di precaricamento non necessario per questa pagina.

<head>
  <!-- ... -->
  <link rel="preload" href="main.css" as="style">
  <link rel="preload" href="details.css" as="style">
</head>

Per un elenco di tutti i tipi di risorse che possono essere recuperati insieme ai valori corretti da utilizzare per l'attributo as, consulta l'articolo di MDN sul precaricamento.

Precarica le risorse future

Prefetch è un altro suggerimento del browser che può essere utilizzato per effettuare una richiesta di una risorsa utilizzata per un percorso di navigazione diverso, ma con una priorità inferiore rispetto ad altre risorse importanti necessarie per la pagina corrente.

In questo sito web, se fai clic sull'immagine, viene visualizzato un percorso details/ separato.

Dettagli della route

Un file CSS separato, details.css, contiene tutti gli stili necessari per questa pagina semplice. Aggiungi un elemento link a index.html per precaricare questa risorsa.

<head>
  <!-- ... -->
  <link rel="prefetch" href="details.css">
</head>

Per capire come viene attivata una richiesta per il file, apri il riquadro Rete in DevTools e deseleziona l'opzione Disattiva cache.

Disattivare la cache in Chrome DevTools

Ricarica l'applicazione e nota come viene effettuata una richiesta a priorità molto bassa per details.css dopo che tutti gli altri file sono stati recuperati.

Riquadro Network con risorsa precaricata

Con DevTools aperto, fai clic sull'immagine sul sito web per andare alla pagina details. Poiché in details.html viene utilizzato un elemento link per recuperare details.css, viene effettuata una richiesta per la risorsa come previsto.

Richieste di rete della pagina dei dettagli

Fai clic sulla richiesta di rete details.css in DevTools per visualizzarne i dettagli. Noterai che il file viene recuperato dalla cache su disco del browser.

Richiesta di dettagli recuperata dalla cache del disco

Sfruttando il tempo di inattività del browser, il recupero anticipato effettua una richiesta anticipata di una risorsa necessaria per un'altra pagina. In questo modo, le richieste di navigazione future vengono accelerate consentendo al browser di memorizzare nella cache l'asset in anticipo e di pubblicarlo dalla cache quando necessario.

Precaricamento e prefetching con webpack

Il post Reduce JavaScript payloads with code splitting esplora l'utilizzo delle importazioni dinamiche per dividere un bundle in più blocchi. Ciò viene dimostrato con una semplice applicazione che importa dinamicamente un modulo da Lodash quando viene inviato un modulo.

App Magic Sorter che mostra la suddivisione del codice

Puoi accedere al problema relativo a questa applicazione qui.

Il seguente blocco di codice, che si trova in src/index.js,, è responsabile dell'importazione dinamica del metodo quando si fa clic sul pulsante.

form.addEventListener("submit", e => {
  e.preventDefault()
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

La suddivisione di un bundle migliora i tempi di caricamento della pagina riducendone le dimensioni iniziali. La versione 4.6.0 di webpack supporta il precaricamento o il recupero anticipato dei chunk importati dinamicamente. Utilizzando questa applicazione come esempio, il metodo lodash può essere precaricato durante il tempo di inattività del browser; quando un utente preme il pulsante, non si verifica alcun ritardo nel recupero della risorsa.

Utilizza il parametro di commento specifico webpackPrefetch all'interno di un'importazione dinamica per precaricare un particolare blocco. Ecco come apparirebbe con questa particolare applicazione.

form.addEventListener("submit", e => {
  e.preventDefault()
  import(/* webpackPrefetch: true */ 'lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});

Una volta ricaricata l'applicazione, webpack inserisce un tag di precaricamento per la risorsa nell'intestazione del documento. Puoi visualizzarlo nel riquadro Elementi in DevTools.

Riquadro degli elementi con tag di precaricamento

L'osservazione delle richieste nel riquadro Rete mostra anche che questo blocco viene recuperato con una priorità bassa dopo che sono state richieste tutte le altre risorse.

Riquadro Network con richiesta precaricata

Sebbene il recupero anticipato abbia più senso per questo caso d'uso, webpack supporta anche il precaricamento dei chunk importati dinamicamente.

import(/* webpackPreload: true */ 'module')

Conclusione

Con questo codelab, dovresti avere una solida comprensione di come il precaricamento o il recupero anticipato di determinati asset possa migliorare l'esperienza utente del tuo sito. È importante ricordare che queste tecniche non devono essere utilizzate per ogni risorsa e che un utilizzo errato può compromettere le prestazioni. I risultati migliori si ottengono solo con il precaricamento o il recupero selettivo.

In sintesi:

  • Utilizza preload per le risorse rilevate in ritardo, ma fondamentali per la pagina corrente.
  • Utilizza il prefetch per le risorse necessarie per un futuro percorso di navigazione o azione dell'utente.

Non tutti i browser supportano attualmente sia il precaricamento che il recupero preliminare. Ciò significa che non tutti gli utenti della tua applicazione potrebbero notare miglioramenti delle prestazioni.

Se vuoi maggiori informazioni su aspetti specifici di come il precaricamento e il recupero anticipato possono influire sulla tua pagina web, consulta questi articoli: