Mise en cache

Le stockage en cache est un outil puissant. Cela rend vos applications moins dépendantes des conditions du réseau. En utilisant correctement les caches, vous pouvez rendre votre application Web disponible hors connexion et diffuser vos composants aussi rapidement que possible dans n'importe quelle condition réseau. Comme indiqué dans la section Composants et données, vous pouvez choisir la meilleure stratégie de mise en cache des composants nécessaires. Pour gérer le cache, votre service worker interagit avec l'API Cache Storage.

Navigateurs pris en charge

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

Source

L'API Cache Storage est disponible dans différents contextes:

  • Contexte de la fenêtre (thread principal de votre PWA).
  • Le service worker.
  • Tout autre nœud que vous utilisez.

L'un des avantages de la gestion du cache à l'aide de service workers est que son cycle de vie n'est pas lié à la fenêtre, ce qui signifie que vous ne bloquez pas le thread principal. Notez que pour utiliser l'API Cache Storage, la plupart de ces contextes doivent être associés à une connexion TLS.

Éléments à mettre en cache

La première question que vous vous posez peut-être concernant le cache est "Que mettre en cache ?". Il n'existe pas de réponse unique à cette question, mais vous pouvez commencer par toutes les ressources minimales dont vous avez besoin pour afficher l'interface utilisateur.

Ces ressources doivent inclure les éléments suivants:

  • Code HTML de la page principale (start_url de votre application).
  • Feuilles de style CSS requises pour l'interface utilisateur principale.
  • Images utilisées dans l'interface utilisateur.
  • Fichiers JavaScript requis pour afficher l'interface utilisateur.
  • Données (par exemple, un fichier JSON) requises pour afficher une expérience de base.
  • Polices Web
  • Dans une application multipage, d'autres documents HTML que vous souhaitez diffuser rapidement ou hors connexion.

Prêt pour le mode hors connexion

Bien que la compatibilité hors connexion soit l'une des exigences d'une progressive web app (PWA), il est essentiel de comprendre que toutes les PWA n'ont pas besoin d'une expérience hors connexion complète, par exemple les solutions de jeu en nuage ou les applications d'actifs cryptographiques. Il est donc acceptable d'offrir une interface utilisateur de base pour guider vos utilisateurs dans ces situations.

Votre PWA ne doit pas afficher le message d'erreur du navigateur indiquant que le moteur de rendu Web n'a pas pu charger la page. Utilisez plutôt votre service worker pour afficher vos propres messages, ce qui évite d'afficher un message d'erreur générique et déroutant dans le navigateur.

Vous pouvez utiliser de nombreuses stratégies de mise en cache différentes en fonction des besoins de votre PWA. C'est pourquoi il est important de concevoir votre utilisation du cache pour offrir une expérience rapide et fiable. Par exemple, si tous les éléments de votre application se téléchargent rapidement, ne consomment pas beaucoup d'espace et n'ont pas besoin d'être mis à jour à chaque requête, la mise en cache de tous vos éléments est une stratégie valide. Si, en revanche, vous disposez de ressources qui doivent être à la dernière version, vous pouvez envisager de ne pas du tout les mettre en cache.

Utilisation de l'API

Utilisez l'API Cache Storage pour définir un ensemble de caches dans votre origine, chacun étant identifié par un nom de chaîne que vous pouvez définir. Accédez à l'API via l'objet caches. La méthode open permet de créer ou d'ouvrir un cache déjà créé. La méthode open renvoie une promesse pour l'objet de cache.

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

Télécharger et stocker des éléments

Pour demander au navigateur de télécharger et de stocker les éléments, utilisez les méthodes add ou addAll. La méthode add envoie une requête et stocke une réponse HTTP, tandis que addAll stocke un groupe de réponses HTTP en tant que transaction basée sur un tableau de requêtes ou d'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'interface de stockage du cache stocke l'intégralité d'une réponse, y compris tous les en-têtes et le corps. Vous pouvez donc le récupérer ultérieurement à l'aide d'une requête HTTP ou d'une URL en tant que clé. Vous découvrirez comment procéder dans le chapitre "Service".

Quand mettre en cache

Dans votre PWA, vous êtes responsable de décider quand mettre en cache les fichiers. Bien qu'il soit possible de stocker autant d'éléments que possible lorsque le service worker est installé, ce n'est généralement pas la meilleure idée. La mise en cache de ressources inutiles gaspille de la bande passante et de l'espace de stockage, et peut entraîner la diffusion de ressources obsolètes non intentionnelles par votre application.

Vous n'avez pas besoin de mettre en cache tous les composants en même temps. Vous pouvez les mettre en cache plusieurs fois au cours du cycle de vie de votre PWA, par exemple:

  • Lors de l'installation du service worker.
  • Après le premier chargement de la page.
  • Lorsque l'utilisateur accède à une section ou à un itinéraire
  • Lorsque le réseau est inactif.

Vous pouvez demander la mise en cache de nouveaux fichiers dans le thread principal ou dans le contexte du service worker.

Mettre en cache des composants dans un service worker

L'un des scénarios les plus courants consiste à mettre en cache un ensemble minimal d'éléments lorsque le service worker est installé. Pour ce faire, vous pouvez utiliser l'interface de stockage du cache dans l'événement install du service worker.

Étant donné que le thread du service worker peut être arrêté à tout moment, vous pouvez demander au navigateur d'attendre la fin de la promesse addAll pour augmenter les chances de stocker tous les composants et de maintenir la cohérence de l'application. L'exemple suivant montre comment procéder à l'aide de la méthode waitUntil de l'argument d'événement reçu dans l'écouteur d'événement du 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);
      });
   );
});

La méthode waitUntil() reçoit une promesse et demande au navigateur d'attendre que la tâche de la promesse soit résolue (exécutée ou échouée) avant de terminer le processus du service worker. Vous devrez peut-être enchaîner des promesses et renvoyer les appels add() ou addAll() afin qu'un seul résultat soit transmis à la méthode waitUntil().

Vous pouvez également gérer les promesses à l'aide de la syntaxe async/await. Dans ce cas, vous devez créer une fonction asynchrone pouvant appeler await et renvoyant une promesse à waitUntil() après son appel, comme dans l'exemple suivant:

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

Requêtes multidomaines et réponses opaques

Votre PWA peut télécharger et mettre en cache des composants à partir de votre origine et de domaines croisés, tels que le contenu de CDN tiers. Avec une application multidomaine, l'interaction avec le cache est très semblable aux requêtes de même origine. La requête est exécutée et une copie de la réponse est stockée dans votre cache. Comme pour les autres éléments mis en cache, il ne peut être utilisé que dans l'origine de votre application.

L'asset sera stocké en tant que réponse opaque, ce qui signifie que votre code ne pourra pas voir ni modifier le contenu ni les en-têtes de cette réponse. De plus, les réponses opaques n'exposent pas leur taille réelle dans l'API de stockage, ce qui affecte les quotas. Certains navigateurs affichent de grandes tailles, comme 7 Mo, même si le fichier ne fait que 1 Ko.

Mettre à jour et supprimer des éléments

Vous pouvez mettre à jour des composants à l'aide de cache.put(request, response) et les supprimer à l'aide de delete(request).

Pour en savoir plus, consultez la documentation sur l'objet Cache.

Déboguer l'espace de stockage du cache

De nombreux navigateurs proposent un moyen de déboguer le contenu du stockage en cache dans l'onglet "Application" de DevTools. Vous pouvez y voir le contenu de chaque cache de l'origine actuelle. Nous en parlerons plus en détail dans le chapitre "Outils et débogage".

Débogage du contenu du cache de stockage dans les outils pour les développeurs Chrome

Ressources