Esperienze di navigazione istantanee

Integrazione delle tecniche di precaricamento tradizionali con i service worker.

Demián Renzulli
Demián Renzulli
Gilberto Cocchi
Gilberto Cocchi

L'esecuzione di un'attività su un sito di solito comporta diversi passaggi. Ad esempio, l'acquisto di un prodotto in un sito web di e-commerce potrebbe comportare la ricerca di un prodotto, la scelta di un articolo dall'elenco dei risultati, l'aggiunta dell'articolo al carrello e il completamento dell'operazione mediante il pagamento.

In termini tecnici, spostarsi tra pagine diverse significa effettuare una richiesta di navigazione. Come regola generale, non vuoi utilizzare intestazioni Cache-Control di lunga durata per memorizzare nella cache la risposta HTML per una richiesta di navigazione. Normalmente dovrebbero essere soddisfatti tramite la rete, con Cache-Control: no-cache, per garantire che il codice HTML, insieme alla catena di richieste di rete successive, sia (ragionevolmente) aggiornato. Purtroppo ogni volta che l'utente accede alla rete da rete ogni volta che accede a una nuova pagina, la navigazione potrebbe risultare lenta, quanto meno significa non essere affidabile veloce.

Per velocizzare queste richieste, se puoi prevedere l'azione dell'utente, puoi richiedere preventivamente queste pagine e questi asset e conservarli nella cache per un breve periodo di tempo finché l'utente non fa clic su questi link. Questa tecnica è chiamata precaricamento e viene in genere implementata aggiungendo tag <link rel="prefetch"> alle pagine, indicando la risorsa da precaricare.

In questa guida esploreremo i diversi modi in cui i service worker possono essere utilizzati come complemento delle tecniche di precaricamento tradizionali.

Casi di produzione

MercadoLibre è il più grande sito di e-commerce dell'America Latina. Per velocizzare le navigazioni, inseriscono dinamicamente i tag <link rel="prefetch"> in alcune parti del flusso. Ad esempio, nelle pagine delle schede recuperano la pagina dei risultati successiva non appena l'utente scorre fino alla fine della scheda:

Screenshot della prima e della seconda pagina di schede di MercadoLibre e di un tag Link Prefetch che collegano entrambe.

I file precaricati vengono richiesti con la priorità "Più bassa" e archiviati nella cache HTTP o nella cache in memoria (a seconda che la risorsa possa essere memorizzata o meno nella cache), per un periodo di tempo che varia a seconda del browser. Ad esempio, a partire da Chrome 85, questo valore è pari a 5 minuti. Le risorse vengono mantenute per cinque minuti, dopodiché vengono applicate le normali regole Cache-Control per la risorsa.

L'utilizzo della memorizzazione nella cache del service worker può aiutarti a estendere la durata delle risorse di precaricamento oltre il periodo di cinque minuti.

Ad esempio, il portale sportivo italiano Virgilio Sport utilizza i lavoratori per i servizi per precaricare i post più popolari nella loro home page. Utilizzano inoltre l'API Network Information per evitare il precaricamento per gli utenti che utilizzano una connessione 2G.

Logo Virgilio Sport.

Come risultato, Virgilio Sport ha osservato che per oltre 3 settimane di osservazione i tempi di caricamento degli articoli sono migliorati del 78% e il numero di impressioni degli articoli è aumentato del 45%.

Uno screenshot della home page e delle pagine degli articoli di Virgilio Sport, con le metriche dell&#39;impatto dopo il precaricamento.

Implementare il pre-memorizzazione nella cache con Workbox

Nella sezione seguente utilizzeremo Workbox per mostrare come implementare diverse tecniche di memorizzazione nella cache nel service worker che possono essere utilizzate come complemento a <link rel="prefetch"> o anche in sostituzione, delegando completamente questa attività al service worker.

1. Pre-cache di pagine statiche e sottorisorse di pagina

La memorizzazione nella cache è la capacità del service worker di salvare i file nella cache durante l'installazione.

Nei seguenti casi, il precaricamento viene utilizzato per raggiungere un obiettivo simile a quello del precaricamento: velocizzare le navigazioni.

PreMemorizzazione nella cache di pagine statiche

Per le pagine generate al momento della creazione (ad es. about.html, contact.html) o in siti completamente statici, è sufficiente aggiungere i documenti del sito all'elenco di precache per renderli già disponibili nella cache ogni volta che l'utente vi accede:

workbox.precaching.precacheAndRoute([
  {url: '/about.html', revision: 'abcd1234'},
  // ... other entries ...
]);

Memorizzazione nella cache delle risorse secondarie della pagina

La memorizzazione nella cache di asset statici che potrebbero essere utilizzate nelle diverse sezioni del sito (ad es. JavaScript, CSS e così via) è una best practice generale e può migliorare ulteriormente gli scenari di precaricamento.

Per velocizzare la navigazione in un sito di e-commerce, puoi utilizzare i tag <link rel="prefetch"> nelle pagine delle schede per precaricare le pagine dei dettagli dei prodotti per i primi prodotti di una pagina di schede. Se hai già pre-memorizzato nella cache le sottorisorse della pagina del prodotto, la navigazione può essere ancora più veloce.

Per implementarlo:

  • Aggiungi un tag <link rel="prefetch"> alla pagina:
 <link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
  • Aggiungi le sottorisorse della pagina all'elenco di pre-cache nel service worker:
workbox.precaching.precacheAndRoute([
  '/styles/product-page.ac29.css',
  // ... other entries ...
]);

2. Prolunga la durata delle risorse di precaricamento

Come accennato in precedenza, <link rel="prefetch"> recupera e conserva le risorse nella cache HTTP per un periodo di tempo limitato, dopodiché vengono applicate le regole Cache-Control relative a una risorsa. A partire da Chrome 85, questo valore è pari a 5 minuti.

I service worker consentono di estendere la durata delle pagine di precaricamento, offrendo al contempo il vantaggio aggiuntivo di rendere queste risorse disponibili per l'utilizzo offline.

Nell'esempio precedente, potresti integrare <link rel="prefetch"> utilizzato per precaricare la pagina di un prodotto con una strategia di memorizzazione nella cache runtime di Workbox.

Per implementarlo:

  • Aggiungi un tag <link rel="prefetch"> alla pagina:
 <link rel="prefetch" href="/phones/smartphone-5x.html" as="document">
  • Implementa una strategia di memorizzazione nella cache di runtime nel service worker per questi tipi di richieste:
new workbox.strategies.StaleWhileRevalidate({
  cacheName: 'document-cache',
  plugins: [
    new workbox.expiration.Plugin({
      maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
    }),
  ],
});

In questo caso, abbiamo scelto di utilizzare una strategia di riconvalida "inattiva". Con questa strategia, le pagine possono essere richieste in parallelo sia dalla cache sia dalla rete. La risposta proviene dalla cache, se disponibile, altrimenti dalla rete. La cache viene sempre aggiornata con la risposta della rete per ogni richiesta andata a buon fine.

3. Delegare il precaricamento al service worker

Nella maggior parte dei casi l'approccio migliore è utilizzare <link rel="prefetch">. Il tag è un suggerimento per una risorsa progettato per rendere il precaricamento il più efficiente possibile.

In alcuni casi, tuttavia, potrebbe essere meglio delegare completamente questa attività al service worker. Ad esempio, per precaricare i primi prodotti in una pagina della scheda di prodotto visualizzata sul lato client, potrebbe essere necessario inserire diversi tag <link rel="prefetch"> nella pagina in modo dinamico, in base a una risposta dell'API. Ciò può richiedere temporaneamente del tempo nel thread principale della pagina e rendere più difficile l'implementazione.

In questi casi, utilizza una "strategia di comunicazione "page to service worker" per delegare l'attività di precaricamento completo al service worker. Questo tipo di comunicazione può essere ottenuto utilizzando worker.postMessage():

Un&#39;icona di una pagina che comunica con un service worker.

Il pacchetto Workbox Window semplifica questo tipo di comunicazione, astraendo molti dettagli della chiamata sottostante che viene effettuata.

Il precaricamento con la finestra di Workbox può essere implementato nel seguente modo:

  • Nella pagina, chiama il service worker trasmettendogli il tipo di messaggio e l'elenco di URL da precaricare:
const wb = new Workbox('/sw.js');
wb.register();

const prefetchResponse = await wb.messageSW({type: 'PREFETCH_URLS', urls: […]});
  • Nel service worker: implementa un gestore di messaggi per inviare una richiesta fetch() per ogni URL da precaricare:
addEventListener('message', (event) => {
  if (event.data.type === 'PREFETCH_URLS') {
    // Fetch URLs and store them in the cache
  }
});