Memorizzazione nella cache

L'archiviazione nella cache è uno strumento potente. Rende le tue app meno dipendenti dalle condizioni di rete. Con un buon utilizzo delle cache, puoi rendere disponibile la tua app web offline e pubblicare i tuoi asset il più rapidamente possibile in qualsiasi condizione di rete. Come indicato in Asset e dati, puoi decidere la strategia migliore per memorizzare nella cache gli asset necessari. Per gestire la cache con cui interagisce il service worker, utilizza l'API Cache Storage.

Browser Support

  • Chrome: 43.
  • Edge: 16.
  • Firefox: 41.
  • Safari: 11.1.

Source

L'API Cache Storage è disponibile in diversi contesti:

  • Il contesto della finestra (il thread principale della PWA).
  • Il service worker.
  • Qualsiasi altro lavoratore che utilizzi.

Un vantaggio della gestione della cache tramite i service worker è che il suo ciclo di vita non è legato alla finestra, il che significa che non stai bloccando il thread principale. Tieni presente che per utilizzare l'API Cache Storage, la maggior parte di questi contesti deve essere in una connessione TLS.

Cosa memorizzare nella cache

La prima domanda che potresti porti sulla memorizzazione nella cache è cosa memorizzare nella cache. Anche se non esiste una risposta univoca a questa domanda, puoi iniziare con tutte le risorse minime necessarie per il rendering dell'interfaccia utente.

Queste risorse devono includere:

  • Il codice HTML della pagina principale (start_url dell'app).
  • Fogli di stile CSS necessari per l'interfaccia utente principale.
  • Immagini utilizzate nell'interfaccia utente.
  • File JavaScript necessari per il rendering dell'interfaccia utente.
  • Dati, ad esempio un file JSON, necessari per il rendering di un'esperienza di base.
  • Caratteri web.
  • In un'applicazione multipagina, altri documenti HTML che vuoi pubblicare rapidamente o offline.

Pronto per la modalità offline

Sebbene la funzionalità offline sia uno dei requisiti per un'app web progressiva, è essenziale capire che non tutte le PWA hanno bisogno di un'esperienza offline completa, ad esempio le soluzioni di cloud gaming o le app di criptoasset. Pertanto, è accettabile offrire un'interfaccia utente di base che guidi gli utenti in queste situazioni.

La PWA non deve visualizzare un messaggio di errore del browser che indica che il motore di rendering web non è riuscito a caricare la pagina. Utilizza invece il service worker per mostrare i tuoi messaggi, evitando un errore del browser generico e fuorviante.

Esistono molte strategie di memorizzazione nella cache diverse che puoi utilizzare a seconda delle esigenze della tua PWA. Per questo motivo è importante progettare l'utilizzo della cache in modo da offrire un'esperienza rapida e affidabile. Ad esempio, se tutte le risorse dell'app vengono scaricate rapidamente, non occupano molto spazio e non devono essere aggiornate a ogni richiesta, la memorizzazione nella cache di tutte le risorse sarebbe una strategia valida. Se, d'altra parte, hai risorse che devono essere nella versione più recente, ti consigliamo di non memorizzare nella cache questi asset.

Utilizzo dell'API

Utilizza l'API Cache Storage per definire un insieme di cache all'interno dell'origine, ognuna identificata da un nome stringa che puoi definire. Accedi all'API tramite l'oggetto caches e il metodo open consente la creazione o l'apertura di una cache già creata. Il metodo open restituisce una promessa per l'oggetto cache.

caches.open("pwa-assets")
.then(cache => {
  // you can download and store, delete or update resources with cache arguments
});

Download e archiviazione degli asset

Per chiedere al browser di scaricare e archiviare gli asset, utilizza i metodi add o addAll. Il metodo add effettua una richiesta e memorizza una risposta HTTP, mentre addAll un gruppo di risposte HTTP come transazione in base a un array di richieste o URL.

caches.open("pwa-assets")
.then(cache => {
  cache.add("styles.css"); // it stores only one resource
  cache.addAll(["styles.css", "app.js"]); // it stores two resources
});

L'interfaccia di archiviazione della cache memorizza l'intera risposta, incluse tutte le intestazioni e il corpo. Di conseguenza, puoi recuperarlo in un secondo momento utilizzando una richiesta HTTP o un URL come chiave. Vedrai come farlo nel capitolo sulla pubblicazione.

Quando memorizzare nella cache

Nella tua PWA, sei tu a decidere quando memorizzare i file nella cache. Sebbene un approccio sia quello di archiviare il maggior numero possibile di asset durante l'installazione del service worker, in genere non è la soluzione migliore. La memorizzazione nella cache di risorse non necessarie spreca larghezza di banda e spazio di archiviazione e potrebbe causare la pubblicazione di risorse obsolete non intenzionali da parte della tua app.

Non è necessario memorizzare nella cache tutti gli asset contemporaneamente. Puoi memorizzarli nella cache più volte durante il ciclo di vita della tua PWA, ad esempio:

  • All'installazione del service worker.
  • Dopo il primo caricamento della pagina.
  • Quando l'utente accede a una sezione o a un percorso.
  • Quando la rete è inattiva.

Puoi richiedere la memorizzazione nella cache di nuovi file nel thread principale o nel contesto del service worker.

Memorizzazione nella cache degli asset in un service worker

Uno degli scenari più comuni è memorizzare nella cache un insieme minimo di asset quando viene installato il service worker. Per farlo, puoi utilizzare l'interfaccia di archiviazione della cache all'interno dell'evento install nel service worker.

Poiché il thread del service worker può essere interrotto in qualsiasi momento, puoi richiedere al browser di attendere il completamento della promessa addAll per aumentare la possibilità di archiviare tutte le risorse e mantenere la coerenza dell'app. Il seguente esempio mostra come eseguire questa operazione utilizzando il metodo waitUntil dell'argomento evento ricevuto nel listener di eventi del service worker.

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
   event.waitUntil(
      caches.open("pwa-assets")
      .then(cache => {
         return cache.addAll(urlsToCache);
      });
   );
});

Il metodo waitUntil() riceve una promessa e chiede al browser di attendere che l'attività nella promessa venga risolta (completata o non riuscita) prima di terminare il processo del service worker. Potresti dover concatenare le promesse e restituire le chiamate add() o addAll() in modo che un singolo risultato arrivi al metodo waitUntil().

Puoi anche gestire le promesse utilizzando la sintassi async/await. In questo caso, devi creare una funzione asincrona che possa chiamare await e che restituisca una promessa a waitUntil() dopo essere stata chiamata, come nel seguente esempio:

const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
   let cacheUrls = async () => {
      const cache = await caches.open("pwa-assets");
      return cache.addAll(urlsToCache);
   };
   event.waitUntil(cacheUrls());
});

Richieste multiorigine e risposte opache

La tua PWA può scaricare e memorizzare nella cache gli asset dall'origine e dai domini cross-domain, ad esempio i contenuti delle CDN di terze parti. Con un'app cross-domain, l'interazione con la cache è molto simile alle richieste per la stessa origine. La richiesta viene eseguita e una copia della risposta viene memorizzata nella cache. Come per gli altri asset memorizzati nella cache, può essere utilizzato solo nell'origine dell'app.

L'asset verrà archiviato come risposta opaca, il che significa che il codice non potrà visualizzare o modificare i contenuti o le intestazioni della risposta. Inoltre, le risposte opache non espongono le loro dimensioni effettive nell'API Storage, il che influisce sulle quote. Alcuni browser mostrano dimensioni elevate, ad esempio 7 MB, indipendentemente dalle dimensioni del file, anche se è di soli 1 kB.

Aggiornamento ed eliminazione di asset

Puoi aggiornare gli asset utilizzando cache.put(request, response) ed eliminarli con delete(request).

Per ulteriori dettagli, consulta la documentazione relativa all'oggetto Cache.

Debug dello spazio di archiviazione cache

Molti browser offrono un modo per eseguire il debug dei contenuti dell'archivio della cache nella scheda Applicazione di DevTools. Qui puoi visualizzare i contenuti di ogni cache all'interno dell'origine corrente. Parleremo di questi strumenti più nel dettaglio nel capitolo Strumenti e debug.

Debug dei contenuti di Cache Storage di Chrome DevTools.

Risorse