Progressive Web Apps : travailler avec Workbox

1. Bienvenue

Dans cet atelier, vous allez prendre un site Web avec un service worker existant et le convertir pour qu'il utilise Workbox. Il s'agit du deuxième d'une série d'ateliers de programmation complémentaires pour l'atelier sur les progressive web apps. L'atelier de programmation précédent était Passer hors connexion. Il y a six autres ateliers de programmation dans cette série.

Points abordés

  • Convertir un service worker existant pour utiliser Workbox
  • Ajouter un remplacement hors connexion à une PWA

À savoir

  • HTML et JavaScript de base

Ce dont vous avez besoin

2. Préparer l'atelier

Commencez par cloner ou télécharger le code de démarrage nécessaire pour effectuer cet atelier de programmation :

Si vous clonez le dépôt, assurez-vous d'être dans la branche pwa03--workbox. Le fichier ZIP contient également le code de cette branche.

Ce code de base nécessite Node.js 14 ou version ultérieure. Une fois le code disponible, exécutez npm ci à partir de la ligne de commande dans le dossier du code afin d'installer toutes les dépendances dont vous aurez besoin. Ensuite, exécutez npm start pour démarrer le serveur de développement de l'atelier de programmation.

Le fichier README.md du code source fournit une explication pour tous les fichiers distribués. De plus, voici les principaux fichiers existants que vous utiliserez tout au long de cet atelier de programmation :

Fichiers clés

  • service-worker.js : fichier du service worker de l'application
  • offline.html : code HTML hors connexion à utiliser lorsqu'une page n'est pas disponible

3. Migrer vers Workbox

En examinant le service worker existant, le précache semble pouvoir être décomposé en deux étapes :

  • Mettre en cache les fichiers pertinents lors de l'installation du Service Worker
  • Diffuser à nouveau ces fichiers avec une stratégie "Cache Only" (Cache uniquement)

Le fichier index.html et la route / ont toujours un sens pour la mise en cache préalable, car le code HTML de cette application Web ne va pas beaucoup changer. Cependant, les autres fichiers, comme le CSS et le JavaScript, peuvent changer. Nous ne voulons pas avoir à parcourir tout le cycle de vie du service worker à chaque fois qu'ils changent. De plus, le service worker actuel ne prend en compte qu'un sous-ensemble de notre CSS et de notre JavaScript. Nous voulons que tout soit couvert. Il est plus judicieux de mettre ces éléments en cache avec une stratégie "Stale While Revalidate" (Périmé pendant la revalidation) : réponse rapide qui peut être mise à jour en arrière-plan si nécessaire.

Le préchargement revisité

Comme nous migrons vers Workbox, nous n'avons pas besoin de conserver le code existant. Supprimez donc tout le contenu de service-worker.js. Dans l'atelier précédent, nous avons configuré ce Service Worker pour qu'il soit compilé. Nous pouvons donc utiliser les importations ESModule ici pour importer Workbox à partir de ses modules NPM. Commençons par revenir sur le préchargement. Dans service-worker.js, ajoutez le code suivant :

import { warmStrategyCache } from 'workbox-recipes';
import { CacheFirst } from 'workbox-strategies';
import { registerRoute } from 'workbox-routing';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { ExpirationPlugin } from 'workbox-expiration';

// Set up page cache
const pageCache = new CacheFirst({
  cacheName: 'page-cache',
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200],
    }),
    new ExpirationPlugin({
      maxAgeSeconds: 30 * 24 * 60 * 60,
    }),
  ],
});

warmStrategyCache({
  urls: ['/index.html', '/'],
  strategy: pageCache,
});

registerRoute(({ request }) => request.mode === 'navigate', pageCache);

Explication

Pour configurer le préchargement pour /index.html et /, vous devez extraire cinq modules. Cela peut sembler beaucoup, mais ce code est beaucoup plus puissant que le code écrit précédemment.

Il commence par configurer une nouvelle stratégie de mise en cache "Cache First", choisie à la place d'une stratégie "Cache Only" pour permettre d'ajouter d'autres pages au cache si nécessaire. Un nom lui est attribué : page-cache. Les stratégies Workbox peuvent accepter un certain nombre de plug-ins qui peuvent affecter le cycle de vie de l'enregistrement et de la récupération de contenu à partir du cache. Ici, deux plug-ins, le plug-in Cacheable Response et le plug-in Expiration, sont utilisés pour s'assurer que seules les bonnes réponses du serveur sont mises en cache et que chaque élément du cache sera vidé après 30 jours.

Ensuite, le cache de la stratégie est préchauffé avec /index.html et / à l'aide de la recette Workbox pour préchauffer le cache de la stratégie. Ces éléments seront ajoutés à ce cache lors de l'événement d'installation du service worker.

Enfin, une nouvelle route est enregistrée. Toute requête de navigation sur une page sera gérée par cette stratégie "Cache First" (Cache d'abord), en extrayant la réponse du cache ou du réseau, puis en la mettant en cache.

Mise en cache des composants

Maintenant que le préchargement des routes est configuré, il est temps de réimplémenter la mise en cache des ressources du site, à savoir le CSS et le JavaScript. Pour ce faire, commencez par ajouter StaleWhileRevalidate à votre importation workbox-strategies, puis ajoutez le code suivant en bas de votre Service Worker :

// Set up asset cache
registerRoute(
  ({ request }) => ['style', 'script', 'worker'].includes(request.destination),
  new StaleWhileRevalidate({
    cacheName: 'asset-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  }),
);

Explication

Cet itinéraire commence par déterminer si le type de requête est un style, un script ou un nœud de calcul, correspondant à CSS, JavaScript ou Web Workers. Si c'est le cas, il utilise une stratégie "Stale While Revalidate" (Périmé pendant la revalidation), en essayant d'abord de diffuser le contenu à partir du cache, puis en revenant au réseau si ce n'est pas possible, tout en essayant de mettre à jour la version dans le cache à partir du réseau si possible. Comme la stratégie de page, cette stratégie ne met en cache que les bonnes réponses.

4. Ajouter un remplacement hors connexion

Le service worker d'origine ayant été migré vers Workbox, il reste une dernière chose à faire pour éviter que la PWA ne plante en mode hors connexion : ajouter un fallback hors connexion.

Des solutions de remplacement hors connexion peuvent être définies pour tout ce qui peut ne pas être disponible hors connexion : pages, polices, CSS, JavaScript, images, etc. Au minimum, une page de remplacement doit être définie pour toutes les PWA. Ainsi, si un utilisateur accède à une page qui ne se trouve pas dans le cache, il reste dans le contexte de votre application.

Les recettes Workbox fournissent une recette de secours hors connexion qui peut être utilisée à cette fin. Pour l'utiliser, commencez par ajouter offlineFallback à votre importation workbox-recipes, puis ajoutez le code suivant en bas de votre Service Worker :

// Set up offline fallback
offlineFallback({
  pageFallback: '/offline.html',
});

Explication

La recette de secours hors connexion configure une stratégie "Cache uniquement" qui est préremplie avec les secours fournis. Il configure ensuite un gestionnaire de capture Workbox par défaut, qui capture toutes les requêtes de routage ayant échoué (s'il n'y a rien dans le cache et que quelque chose ne peut pas être atteint sur le réseau), extrait le contenu des fichiers concernés du cache et le renvoie en tant que contenu tant que la requête continue d'échouer.

5. Félicitations !

Vous avez appris à utiliser Workbox pour configurer des stratégies de mise en cache pour les routes et à fournir des solutions de secours hors connexion pour votre PWA.

Le prochain atelier de programmation de la série est IndexedDB.