Invalidation du cache en cascade. 2e partie

Dans la première partie de la traduction du matériel consacré à l'invalidation du cache en cascade, nous avons discuté de la nature du problème et envisagé une des solutions, qui consiste à utiliser des cartes d'importation. Son plus est sa facilité de mise en œuvre. Et moins - mauvaise prise en charge du navigateur. Aujourd'hui, nous parlerons d'autres façons de résoudre ce problème.



Approche n ° 2: Travailleurs des services


La deuxième solution au problème consiste à reproduire la fonctionnalité des cartes d'importation à l'aide d'un technicien de service.

Par exemple, en utilisant un technicien de service, vous pouvez écouter les événements de fetch qui visent à charger des matériaux situés à des adresses correspondant aux clés de la carte d'importation. En exécutant ces demandes, vous pouvez télécharger des fichiers dont les noms incluent des hachages de leur contenu:

 const importMap = {  '/main.mjs': '/main-1a2b.mjs',  '/dep1.mjs': '/dep1-b2c3.mjs',  '/dep2.mjs': '/dep2-3c4d.mjs',  '/dep3.mjs': '/dep3-d4e5.mjs',  '/vendor.mjs': '/vendor-5e6f.mjs', }; addEventListener('fetch', (event) => {  const oldPath = new URL(event.request.url, location).pathname;  if (importMap.hasOwnProperty(oldPath)) {    const newPath = importMap[oldPath];    event.respondWith(fetch(new Request(newPath, event.request)));  } }); 

Cependant, compte tenu du fait que le code du technicien de service est indiqué ci-dessus, vous devez comprendre que ce code ne fonctionnera qu'après l'installation et l'activation du technicien de service. Et cela signifie que lorsque vous chargez le site pour la première fois, des fichiers seront demandés sans hachage dans leur nom. Les fichiers avec des hachages dans les noms seront demandés lors des téléchargements ultérieurs du site. En d'autres termes, il s'agit ici d'un double chargement de chaque fichier.

Si vous en tenez compte, il peut sembler que le technicien de service n'est pas une solution appropriée au problème d'invalidation du cache en cascade.

Cependant, ici, je vous demanderai de me permettre de critiquer brièvement les approches de longue date de la mise en cache. Réfléchissons à ce qui se passe si nous cessons d'utiliser des hachages de contenu dans les noms de fichiers, au lieu de mettre les informations de hachage dans le code du service worker.

C'est ainsi que fonctionnent des outils comme Workbox qui pré- mettent en cache les ressources. Ils génèrent des hachages du contenu de chaque fichier à partir de l'assembly et stockent la correspondance des noms de fichiers dans le service worker (il s'avère quelque chose comme une carte d'importation externe). De plus, ils mettent en cache les ressources lors de la première installation d'un service worker et ajoutent des écouteurs d'événement d' fetch qui renvoient des fichiers mis en cache en réponse à des requêtes dont les adresses correspondent à celles de la carte d'importation.

Bien que l'idée que le client reçoive des fichiers qui ne contiennent pas d'informations sur les versions de leur contenu peut sembler effrayante (et contredire tout ce qui vous a été enseigné), la demande de téléchargement de la ressource correspondante n'est exécutée que lorsque le technicien de service est installé. Les autres demandes de téléchargement d'une telle ressource passent par l'API de stockage en cache (qui n'utilise pas d'en-têtes de mise en cache), et les nouvelles demandes au serveur ne sont exécutées que lorsqu'une nouvelle version de l'employé de service est déployée (et vous avez quand même besoin d'une nouvelle version de ces fichiers).

Par conséquent, jusqu'à ce que vous commenciez à déployer de nouvelles versions de modules sans mettre à jour le service worker (ce qui n'est certainement pas recommandé), vous ne rencontrerez jamais de conflit ou de non-concordance de version.

Pour organiser la mise en cache préliminaire des fichiers à l'aide de la bibliothèque de mise en cache de la boîte de travail, vous pouvez transmettre les adresses de fichier et les chaînes avec les informations de version de ces fichiers à la méthode de bibliothèque precacheAndRoute() :

 import {preacacheAndRoute} from 'workbox-precaching'; precacheAndRoute([  {url: '/main.mjs', revision: '1a2b'},  {url: '/dep1.mjs', revision: 'b2c3'},  {url: '/dep2.mjs', revision: '3c4d'},  {url: '/dep3.mjs', revision: 'd4e5'},  {url: '/vendor.mjs', revision: '5e6f'}, ]); 

La façon exacte de générer des lignes avec des versions dépend du développeur lui-même. Mais s'il ne veut pas les créer lui-même, la tâche de générer un manifeste de pré-cache aidera à simplifier les packages workbox-build , workbox-cli et workbox-webpack-plugin (ils peuvent même générer tout le code du service worker).

Mon projet de démonstration contient un exemple d'implémentation de la mise en cache préliminaire à l'aide d'un service worker dans une application workbox-cli (en utilisant workbox-cli ) et dans une application webpack (en utilisant workbox-webpack-plugin ).

Approche n ° 3: scripts personnalisés pour le chargement des ressources


Si votre site n'a pas la possibilité d'utiliser des cartes d'importation ou des techniciens de maintenance, voici la troisième approche pour résoudre le problème. Il consiste à implémenter la fonctionnalité d'importer des cartes à l'aide de son propre script de chargement des ressources.

Si vous connaissez les chargeurs de modules de style AMD (comme SystemJS ou RequireJS ), vous savez peut-être également que ces chargeurs de modules prennent généralement en charge les alias de module. En fait, SystemJS prend en charge l' alias en utilisant la syntaxe d'importation de carte. En conséquence, notre problème est facilement résolu de telle manière que cette solution sera tournée vers l'avenir (et, en outre, fonctionnera dans tous les navigateurs existants).

Si vous utilisez Rollup, vous pouvez définir l'option output.format sur system . Dans ce cas, la création d'une carte d'importation pour l'application sera effectuée de la même manière que celle décrite dans la description de la première approche pour résoudre le problème de l'invalidation du cache en cascade.

Mon application de démonstration contient un exemple de site où Rollup est utilisé pour créer des matériaux dans un format adapté à SystemJS et pour créer une carte d'importation avec laquelle télécharger des versions hachées de fichiers.

▍Webpack et chargement des ressources à l'aide de scripts


Webpack peut également vous aider à charger des ressources à l'aide de votre propre script, mais le chargeur généré par webpack, contrairement aux chargeurs AMD classiques, est unique pour chaque ensemble spécifique.

L'avantage de cette approche est que le runtime du webpack peut (et donc qu'il fonctionne réellement) inclure ses propres mappages entre les noms / identifiants des fragments et leurs adresses (c'est similaire à ce que je recommande ici). Cela signifie que les bundles de webpack qui utilisent le fractionnement de code sont moins susceptibles de subir une invalidation du cache en cascade.

En fait, la bonne nouvelle pour les utilisateurs de webpack est que s'ils ont correctement configuré l'assembly du projet à l'aide de webpack (en divisant le code en fragments, comme décrit dans le guide de mise en cache du webpack), une modification du code d'un module individuel ne doit pas conduire à l'invalidation plus de deux fragments (l'un est celui qui contient le module modifié, le second est celui qui contient le runtime).

Mais j'ai de mauvaises nouvelles pour ceux qui utilisent webpack pour construire des projets. Le fait est que le système de mappage interne de ce bundle n'est pas standard. Cela signifie qu'il ne peut pas être intégré aux outils existants et que l'utilisateur ne peut pas le configurer. Par exemple, vous ne pouvez pas générer indépendamment des fichiers de sortie (c'est-à-dire faire comme décrit dans l'histoire de la première approche pour résoudre le problème) et mettre vos propres hachages dans le mappage. Et c'est un inconvénient de webpack, car les hachages utilisés par ce bundler ne sont pas basés sur le contenu des fichiers de sortie , mais sur le contenu des fichiers source et sur la configuration de construction. Et cela peut conduire à de petites et subtiles erreurs (par exemple - ici , ici et ici - des messages sur de telles erreurs).

Si vous utilisez webpack pour créer une application qui utilise également un technicien de service, je recommanderais d'utiliser le plugin workbox-webpack-plugin et la stratégie de mise en cache, qui a été décrite dans la deuxième approche pour résoudre le problème. Le plugin générera des hachages en fonction du contenu de la sortie du webpack, ce qui signifie que vous n'avez pas à vous soucier des erreurs ci-dessus. En plus de cela, travailler avec des noms de fichiers qui n'ont pas de hachage est généralement plus facile que de travailler avec des noms qui ont des hachages.

Autres ressources de projet Web


Plus tôt, j'ai expliqué comment le fait de travailler dans des programmes JavaScript avec des noms de fichiers "hachés" contenant du code de programme peut entraîner l'invalidation du cache en cascade. Mais ce problème s'applique à d'autres matériaux de projet Web.

Ainsi, les fichiers CSS et SVG font souvent référence à d'autres ressources (images, par exemple), dont les noms peuvent contenir des informations sur les versions des fichiers correspondants sous forme de hachages. Comme dans le cas des fichiers JS, pour résoudre le problème de l'invalidation du cache en cascade causée par les changements de noms de ressources similaires, vous pouvez utiliser des cartes d'importation ou des techniciens de maintenance.

Pour les ressources comme les images et les fichiers vidéo, ce n'est pas un problème. Toutes les recommandations existantes s'appliquent ici.

L'essentiel ici est de se rappeler que toujours, lorsque le fichier A télécharge le fichier B et, en outre, inclut des informations sur la version du fichier B en tant que hachage de son contenu, invalider le cache du fichier B entraînera également l'invalidation du cache du fichier A. en travaillant avec des ressources dont l'utilisation est organisée différemment, vous pouvez simplement ignorer les conseils donnés dans ce document.

Résumé


J'espère que cet article vous a inspiré pour regarder de plus près votre site et savoir si le problème de l'invalidation du cache en cascade l'affecte. La façon la plus simple de vérifier cela consiste à assembler le site, à modifier une ligne de code dans un fichier importé par de nombreux modules, puis à reconstruire le site. Si dans le répertoire où se trouvent les résultats de l'assembly, les noms ont changé pour plusieurs fichiers, cela signifie que vous avez un signe d'invalidation du cache en cascade. Et si c'est le cas, vous devrez peut-être penser à utiliser l'une des approches décrites ici pour résoudre ce problème dans votre projet.

Si nous parlons de ce qu'il vaut mieux choisir, alors, franchement, cela dépend de beaucoup.

Lorsque les cartes d'importation seront largement prises en charge par les navigateurs, nous devrons alors faire face à la manière la plus simple et la plus parfaite de traiter l'invalidation du cache en cascade. Mais tant qu'un tel soutien n'est pas disponible, ce mécanisme n'est pas applicable dans la pratique.

Si vous utilisez déjà des techniciens de maintenance, en particulier si vous utilisez Workbox, je recommanderais la deuxième des approches pour résoudre le problème discuté ici. Sur le site sur lequel l'original de ce matériel est publié, la tâche de mise en cache préalable des ressources a été ainsi résolue.

De plus, les employés de service sont la seule option pour ceux qui utilisent des modules JavaScript en production. (Et étant donné que 98% de mes utilisateurs ont des navigateurs qui prennent en charge à la fois les techniciens de maintenance et les modules JS, il ne m'a pas été difficile de choisir cette option).

Si les travailleurs des services ne vous conviennent pas, alors je recommanderais la troisième des approches discutées ici, impliquant l'utilisation de SystemJS. Cette approche est meilleure que les autres, basée sur des scripts de bootloader, tournée vers l'avenir. De là, il sera facile de passer à l'importation de cartes à un moment où leur support apparaîtra dans tous les navigateurs.

Si nous parlons de productivité, le choix de la direction de son optimisation dépend de chaque projet spécifique. Avant d'optimiser les performances, il est important de les mesurer, puis de décider s'il y a un problème et s'il est nécessaire de le traiter. Si vous publiez rarement de nouvelles versions de projet et que les modifications apportées au projet sont généralement à grande échelle, le problème de l'invalidation du cache en cascade peut ne pas vous concerner.

D'un autre côté, si vous déployez souvent de petites modifications de projet, vos utilisateurs qui reviennent peuvent rencontrer le problème de chargement de grandes quantités de code qui existe déjà dans leurs caches. La résolution de ce problème entraînera une augmentation significative des performances de chargement des pages pour ces utilisateurs.

Chers lecteurs! L'invalidation du cache en cascade affecte-t-elle votre projet? Si oui, dites-nous comment vous comptez le résoudre.


Source: https://habr.com/ru/post/fr472862/


All Articles