Gérer les réponses de remplacement

Dans certains cas, vous pouvez mettre en cache une réponse de remplacement si l'utilisateur est hors connexion. L'implémentation d'un remplacement est une alternative aux comportements de mise en cache fournis par des stratégies telles que réseau-first ou stale-while-revalidate.

Une création de remplacement est une réponse générique et universelle qui constitue un meilleur espace réservé que celui fourni par le navigateur par défaut en cas d'échec d'une requête. Par exemple :

  • Une alternative à "l'image manquante" .
  • Alternative HTML à la norme "aucune connexion réseau disponible" .

Page hors connexion uniquement

Si vous avez simplement besoin de fournir une page HTML hors connexion personnalisée, mais rien d'autre, voici une recette de base que vous pouvez suivre:

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

setDefaultHandler(new NetworkOnly());

offlineFallback();

Le code ci-dessus utilise setDefaultHandler afin d'utiliser une stratégie réseau uniquement comme stratégie par défaut pour toutes les routes. Il exécute ensuite la recette offlineFallback pour diffuser la création de remplacement hors connexion en cas d'erreur. Cette recette suppose que votre fichier HTML de remplacement hors connexion sera nommé offline.html et diffusé à partir de la racine de votre serveur Web.

Créations de remplacement complètes

En cas de défaillance du réseau ou d'échec du cache, les stratégies de mise en cache proposées par workbox-strategies rejettent systématiquement les mises en cache. Cela favorise le modèle de définition d'un piège global pour gérer les échecs d'une seule fonction de gestionnaire, ce qui vous permet de proposer différentes solutions de remplacement pour différentes valeurs request.destination.

L'exemple suivant utilise la recette warmStrategyCache de workbox-recipes et définit un gestionnaire d'interception pour diffuser les éléments mis en cache à l'avance dans le cache de l'environnement d'exécution. Toutefois, la mise en cache préalable de remplacement peut être une meilleure option pour votre application:

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();
  }
});

Dans cet exemple, les réponses de remplacement sont mises en pré-cache à l'aide de injectManifest avec les outils de compilation de Workbox et servent de solution de secours en cas d'erreur avec la méthode 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();
  }
});

Exemple de cas d'utilisation pour la deuxième configuration de remplacement : si une page a été mise en cache à l'avance, mais que les images (ou d'autres éléments) demandées par la page ne l'ont pas été. La page peut toujours être lue dans le cache lorsque l'utilisateur est hors connexion, mais des espaces réservés de remplacement ou d'autres fonctionnalités peuvent être fournis en cas d'erreur réseau.

Préchauffer le cache de l'environnement d'exécution

Workbox gère des caches distincts pour la pré-mise en cache et les caches d'exécution, et il peut arriver que vous souhaitiez mettre en cache quelque chose à l'avance sans utiliser la mise en cache préalable. En effet, les mises à jour du fichier manifeste de pré-cache nécessitent le déploiement d'un service worker mis à jour.

Pour préparer le cache de l'environnement d'exécution à l'avance avec des éléments, vous pouvez utiliser la recette warmStrategyCache de workbox-recipes. En arrière-plan, cette stratégie appelle Cache.addAll dans l'événement install d'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});

Conclusion

La gestion des réponses de remplacement aux requêtes ayant échoué demande un peu de travail, mais avec un peu de planification préalable, vous pouvez configurer votre application Web afin de fournir un certain niveau de contenu et de fonctionnalités lorsque l'utilisateur est hors connexion.