Gestione delle risposte di fallback

In determinate situazioni, potresti volere una risposta di riserva memorizzata nella cache nel caso in cui l'utente sia offline. L'implementazione di un fallback è un'alternativa ai comportamenti di memorizzazione nella cache, offerti da strategie come network-first o stale-Mentre-convalida.

Un fallback è una risposta generica adatta a tutti che rappresenta un segnaposto migliore di quello che il browser fornirebbe per impostazione predefinita quando una richiesta non va a buon fine. Ecco alcuni esempi:

  • Un'alternativa a "immagine mancante" segnaposto.
  • Un'alternativa HTML allo standard "Nessuna connessione di rete disponibile" .

Solo pagina offline

Se non devi fare altro che fornire una pagina HTML offline personalizzata, ma nient'altro, puoi seguire questa formula di base:

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

Il codice riportato sopra utilizza setDefaultHandler per una strategia solo rete come predefinita per tutte le route. Quindi esegue la formula offlineFallback per pubblicare il video di riserva offline nel caso in cui si verifichi un errore. La formula presuppone che il tuo file HTML di riserva offline sia denominato offline.html e pubblicato dalla directory principale del tuo server web.

Fallback esaustivi

Ogni volta che si verifica un errore di rete o un fallimento della cache, le strategie di memorizzazione nella cache offerte da workbox-strategies rifiuteranno in modo coerente. Promuove lo schema di impostazione di un "catch" globale per gestire eventuali errori in una singola funzione di gestore, consentendoti di offrire diversi fallback per valori request.destination diversi.

L'esempio seguente utilizza la formula warmStrategyCache di workbox-recipes e imposta un gestore catch per pubblicare in anticipo gli elementi memorizzati nella cache nella cache di runtime. Tuttavia, la pre-memorizzazione nella cache dei fallback potrebbe essere più adatta alla tua applicazione:

import {warmStrategyCache} from 'workbox-recipes';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate} from 'workbox-strategies';

// Fallback assets to cache
const FALLBACK_HTML_URL = '/offline.html';
const FALLBACK_IMAGE_URL = '/images/image-not-found.jpg';
const FALLBACK_STRATEGY = new CacheFirst();

// Warm the runtime cache with a list of asset URLs
warmStrategyCache({
  urls: [FALLBACK_HTML_URL, FALLBACK_IMAGE_URL],
  strategy: FALLBACK_STRATEGY,
});

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // The warmStrategyCache recipe is used to add the fallback assets ahead of
  // time to the runtime cache, and are served in the event of an error below.
  // Use `event`, `request`, and `url` to figure out how to respond, or
  // use request.destination to match requests for specific resource types.
  switch (request.destination) {
    case 'document':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_HTML_URL});

    case 'image':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_IMAGE_URL});

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

In questa fase, le risposte di riserva vengono prememorizzate nella cache utilizzando injectManifest con gli strumenti di creazione di Workbox e utilizzate come alternativa in caso di errore con il metodo matchPrecache.

import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';

// Optional: use the injectManifest mode of one of the Workbox
// build tools to precache a list of URLs, including fallbacks.
precacheAndRoute(self.__WB_MANIFEST);

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // Fallback assets are precached when the service worker is installed, and are
  // served in the event of an error below. Use `event`, `request`, and `url` to
  // figure out how to respond, or use request.destination to match requests for
  // specific resource types.
  switch (request.destination) {
    case 'document':
      // FALLBACK_HTML_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_HTML_URL);

    case 'image':
      // FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_IMAGE_URL);

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

Un esempio di caso d'uso per la seconda configurazione di riserva è se una pagina è stata memorizzata nella cache in anticipo, ma non le immagini (o altri asset) richiesti dalla pagina. La pagina può ancora essere letta dalla cache quando l'utente è offline, ma se si verifica un errore di rete possono essere forniti segnaposto di riserva o funzionalità alternative.

Riscaldamento della cache di runtime

Workbox mantiene cache separate per le cache di pre-memorizzazione e quelle di runtime e potrebbero verificarsi casi in cui potresti voler memorizzare qualcosa in anticipo senza fare affidamento sulla pre-memorizzazione nella cache, poiché per gli aggiornamenti del manifest di pre-memorizzazione nella cache dovrai eseguire il deployment di un Service worker aggiornato.

Per preparare in anticipo la cache di runtime con gli asset, puoi utilizzare la formula warmStrategyCache di workbox-recipes. Dietro le quinte, questa strategia chiama Cache.addAll nell'evento install di un service worker.

import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';

// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = [
  '/offline.html',
];

warmStrategyCache({urls, strategy});

Conclusione

La gestione delle risposte di riserva per le richieste non riuscite richiede un po' di lavoro, ma con un po' di pianificazione in anticipo, puoi configurare la tua app web in modo che fornisca un certo livello di contenuti e funzionalità quando l'utente è offline.