Workbox

Mantenere il service worker e la logica di archiviazione della cache può essere una sfida man mano che la tua PWA cresce. Workbox è un insieme di librerie open source che ti consentono di farlo. Workbox incapsula le API di basso livello, come l'API Service Worker e l'API Cache Storage, ed espone interfacce più adatte agli sviluppatori.

Alcune attività per le quali può essere d'aiuto sono l'abbinamento delle strategie di memorizzazione nella cache ai percorsi (o pattern di routing), l'utilizzo degli stream e l'uso di funzionalità come la sincronizzazione in background con fallback appropriati.

Workbox può aiutarti a gestire le esigenze di pubblicazione e memorizzazione nella cache degli asset. È anche la libreria più utilizzata per i service worker, utilizzata dal 54% dei siti per dispositivi mobili ed è usata in molti strumenti di creazione e interfacce a riga di comando, tra cui l'interfaccia a riga di comando Angular, l'interfaccia a riga di comando Create-React-App e l'interfaccia a riga di comando Vue. Esistono plug-in anche per la maggior parte delle altre librerie e framework, come Next.js.

Il 54%

I siti mobile con service worker utilizzano la libreria Workbox

Moduli di Workbox

Workbox include diverse librerie, chiamate moduli interni, ognuna incentrata su un diverso aspetto della gestione delle risorse e del comportamento dei service worker.

I moduli della casella di lavoro funzionano in diversi contesti, ad esempio:

  • All'interno di un contesto di service worker: importi i moduli che ti servono e li utilizzi dal file del service worker, ad esempio per gestire la memorizzazione nella cache e pubblicare i file con strategie diverse.
  • All'interno del contesto window principale: aiuto per registrare un service worker e comunicare con questo
  • Nell'ambito di un sistema di compilazione, ad esempio webpack, per scopi quali la creazione di un manifest dei tuoi asset o persino la generazione dell'intero service worker.

Alcuni dei moduli più noti sono:

  • workbox-routing: quando il service worker intercetta le richieste, questo modulo le inoltra a diverse funzioni che forniscono risposte; si tratta di un'implementazione del gestore di eventi fetch, come menzionato nel capitolo Pubblicazione.
  • workbox-strategies: un insieme di strategie di memorizzazione nella cache di runtime che gestiscono la risposta a una richiesta, ad esempio cache first e inattive durante la riconvalida; si tratta di un'implementazione delle diverse strategie menzionate nel capitolo Pubblicazione.
  • workbox-precaching: è un'implementazione dei file di memorizzazione nella cache nel gestore di eventi install del service worker (noto anche come precaching), come indicato nel Capitolo Memorizzazione nella cache. Con questo modulo puoi prememorizzare facilmente un insieme di file nella cache e gestire in modo efficiente gli aggiornamenti degli asset. Parleremo dell'aggiornamento delle risorse nel capitolo Aggiornamento.
  • workbox-expiration: è un plug-in utilizzato con le strategie di memorizzazione nella cache per rimuovere le richieste memorizzate nella cache in base al numero di elementi in una cache o in base all'età della richiesta memorizzata nella cache. Consente di gestire le cache e di impostare limiti relativi al tempo e al numero di elementi in ogni cache.
  • workbox-window: un insieme di moduli da eseguire nel contesto della finestra, vale a dire all'interno delle pagine web PWA. Puoi semplificare il processo di registrazione e gli aggiornamenti dei service worker e consentire una comunicazione più semplice tra il codice in esecuzione nel contesto del service worker e quello della finestra.

Utilizzo di Workbox

Workbox offre diversi modi per l'integrazione nella tua PWA. Puoi scegliere quella che si adatta meglio all'architettura della tua app:

  • interfaccia a riga di comando di Workbox: un'utilità a riga di comando che genera un service worker completo, inserisce un manifest di precache o copia i file di Workbox necessari.
  • Build Workbox: un modulo npm che genera un service worker completo, inserisce un manifest di pre-cache e copia i file di Workbox. Questa funzionalità è pensata per essere integrata con il tuo processo di compilazione.
  • workbox-sw: un modo per caricare i pacchetti del service worker di Workbox da una CDN che non utilizza un processo di compilazione.

L'interfaccia a riga di comando di Workbox fornisce una procedura guidata che ti guida nella creazione del service worker. Per eseguire la procedura guidata, digita quanto segue nella riga di comando:

npx workbox-cli wizard

Interfaccia a riga di comando di Workbox in azione in un terminale

Memorizzazione nella cache e pubblicazione con Workbox

Un uso comune di Workbox consiste nell'utilizzare i moduli di routing e delle strategie insieme per memorizzare i file nella cache e gestirli.

Il modulo workbox-strategies fornisce immediatamente le strategie di memorizzazione nella cache descritte nei capitoli Asset e dati e Pubblicazione.

Il modulo workbox-routing consente di ordinare le richieste in arrivo al service worker e di abbinarle alle strategie o funzioni di memorizzazione nella cache per ottenere risposte a queste richieste.

Dopo l'abbinamento delle route alle strategie, Workbox consente anche di filtrare le risposte che verranno aggiunte alla cache con il plug-in workbox-cacheable-response. Con questo plug-in, ad esempio, puoi memorizzare nella cache solo le risposte che sono state restituite senza errori.

Il seguente esempio di codice utilizza una strategia basata sulla cache (tramite il modulo CacheFirst) per memorizzare nella cache e gestire le navigazioni nelle pagine.

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';

const pageStrategy = new CacheFirst({
  // Put all cached files in a cache named 'pages'
  cacheName: 'pages',
  plugins: [
    // Only requests that return with a 200 status are cached
    new CacheableResponsePlugin({
      statuses: [200],
    }),
  ],
});

Il plug-in ti consente di sfruttare la memorizzazione nella cache di Workbox e di richiedere il ciclo di vita della risoluzione. In questo caso, CacheableResponsePlugin viene utilizzato solo per memorizzare nella cache le richieste il cui stato risulta 200, impedendo il salvataggio delle richieste errate nella cache.

Una volta creata la strategia, è il momento di registrare un percorso per utilizzarla. L'esempio seguente chiama registerRoute(), passando un oggetto Request al relativo callback. Se request.mode è "navigate", utilizza la strategia CacheFirst (qui chiamata pageStrategy) definita nell'esempio di codice precedente.

// Cache page navigations (HTML) with a Cache First strategy
registerRoute( ({ request }) => request.mode === 'navigate',
  pageStrategy );

Leggi la documentazione di Workbox per ulteriori esempi e best practice.

Di riserva offline

Il modulo workbox-routing ha anche un file setCatchHandler() esportato, che fornisce la gestione se una route genera un errore. Puoi utilizzarla per configurare un fallback offline per informare gli utenti che il percorso richiesto non è al momento disponibile.

In questo caso, una combinazione di Workbox e API Cache Storage fornisce un fallback offline utilizzando una strategia solo cache. Innanzitutto, durante il ciclo di vita di installazione del service worker, la cache di offline-fallbacks viene aperta e l'array di fallback offline viene aggiunto alla cache.

import { setCatchHandler } from 'workbox-routing';

// Warm the cache when the service worker installs
self.addEventListener('install', event => {
  const files = ['/offline.html']; // you can add more resources here
  event.waitUntil(
    self.caches.open('offline-fallbacks')
        .then(cache => cache.addAll(files))
  );
});

In setCatchHandler() viene quindi determinata la destinazione della richiesta che ha generato un errore e viene aperta la cache di offline-fallbacks. Se la destinazione è un documento, i contenuti di riserva offline vengono restituiti all'utente. Se non esiste o se la destinazione non è un documento (ad esempio un'immagine o un foglio di stile), viene restituita una risposta di errore. Puoi estendere questo pattern non solo per i documenti ma anche per immagini, video, caratteri e qualsiasi cosa tu voglia fornire come riserva offline.

// Respond with the fallback if a route throws an error
setCatchHandler(async (options) => {
  const destination = options.request.destination;
  const cache = await self.caches.open('offline-fallbacks');
  if (destination === 'document') {
    return (await cache.match('/offline.html')) || Response.error();
  }
  return Response.error();
});

Ricette

Diversi pattern di routing e memorizzazione nella cache, come le navigazioni NetworkFirst e i fallback offline, sono abbastanza comuni da essere incapsulati in formule riutilizzabili. Consulta le ricette del workbox perché possono esserti d'aiuto se offrono una soluzione adatta alla tua architettura. In genere sono disponibili sotto forma di singola riga di codice da aggiungere al codice del service worker.

Memorizzazione nella cache e aggiornamento degli asset

La memorizzazione nella cache degli asset comporta anche l'aggiornamento. Workbox ti aiuta ad aggiornare gli asset nel modo che ritieni migliore. Potrebbe essere possibile mantenerli aggiornati se cambiano sul server o attendere la disponibilità di una nuova versione dell'app. Per scoprire di più sugli aggiornamenti, consulta il capitolo Aggiornamento.

Gioca con Workbox

Puoi iniziare subito a usare Workbox utilizzando il seguente codelab:

Risorse