Im
ersten Teil der Übersetzung von Material, das sich mit der kaskadierenden Ungültigmachung des Caches befasst, haben wir die Art des Problems erörtert und eine der Möglichkeiten zur Lösung des Problems in Betracht gezogen, nämlich die Verwendung von Importkarten. Das Plus ist die einfache Implementierung. Und Minus - schlechte Browserunterstützung. Heute werden wir über andere Möglichkeiten zur Lösung dieses Problems sprechen.

Ansatz 2: Servicemitarbeiter
Die zweite Lösung des Problems besteht darin, die Funktionalität von Importkarten mithilfe eines Servicemitarbeiters zu reproduzieren.
Mithilfe eines Servicemitarbeiters können Sie beispielsweise Abrufereignisse abhören, die darauf abzielen, Materialien an Adressen zu laden, die den Schlüsseln der Importkarte entsprechen. Durch Ausführen dieser Anforderungen können Sie Dateien hochladen, deren Namen Hashes ihres Inhalts enthalten:
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))); } });
Unter Berücksichtigung der Tatsache, dass der Service Worker-Code oben angegeben ist, müssen Sie jedoch verstehen, dass dieser Code erst funktioniert, nachdem der Service Worker installiert und aktiviert wurde. Dies bedeutet, dass beim ersten Laden der Site Dateien angefordert werden, deren Namen keine Hashes enthalten. Dateien mit Hashes in den Namen werden bei nachfolgenden Site-Downloads angefordert. Mit anderen Worten, hier geht es um das doppelte Laden jeder Datei.
Wenn Sie dies berücksichtigen, scheint der Service Worker keine geeignete Lösung für das Problem der Kaskadierung der Cache-Ungültigkeit zu sein.
Hier möchte ich Sie jedoch bitten, mir zu erlauben, langjährige Ansätze zum Caching kurz zu kritisieren. Lassen Sie uns darüber nachdenken, was passiert, wenn wir keine Content-Hashes mehr in den Dateinamen verwenden, anstatt die Hash-Informationen in den Service Worker-Code einzufügen.
So funktionieren Tools wie
Workbox , mit denen Ressourcen vorab zwischengespeichert werden. Sie generieren Hashes des Inhalts jeder Datei aus der Assembly und speichern die Entsprechung der Dateinamen im Servicemitarbeiter (es stellt sich heraus, dass es sich um eine externe Importkarte handelt). Darüber hinaus zwischenspeichern sie Ressourcen während der ersten Installation eines Service Workers und fügen Listener für Abrufereignisse hinzu, die zwischengespeicherte Dateien als Antwort auf Anforderungen zurückgeben, deren Adressen denen in der Importzuordnung entsprechen.
Obwohl die Idee, dass der Client Dateien empfängt, die keine Informationen über die Versionen ihres Inhalts enthalten, beängstigend erscheint (und allem widerspricht, was Ihnen beigebracht wurde), wird die Anforderung zum Herunterladen der entsprechenden Ressource nur ausgeführt, wenn der Service Worker installiert ist. Weitere Anforderungen zum Herunterladen einer solchen Ressource werden über
die Cache-Speicher-API (die keine Caching-Header verwendet) ausgeführt. Neue Anforderungen an den Server werden nur ausgeführt, wenn eine neue Version des Service Workers bereitgestellt wird (und Sie ohnehin eine neue Version dieser Dateien benötigen).
Bis Sie mit der Bereitstellung neuer Versionen von Modulen beginnen, ohne den Service Worker zu aktualisieren (und dies wird definitiv nicht empfohlen), werden Sie daher niemals auf einen Konflikt oder eine Versionsinkongruenz stoßen.
Um das vorläufige Zwischenspeichern von Dateien mithilfe der
Workbox-Precaching-Bibliothek zu organisieren, können Sie die
Dateiadressen und Zeichenfolgen mit den Versionsinformationen dieser Dateien an die Bibliotheksmethode
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'}, ]);
Wie genau Zeilen mit Versionen generiert werden, ist Sache des Entwicklers. Wenn er sie jedoch nicht selbst erstellen möchte, vereinfacht die Erstellung eines Pre-Cache-Manifests die
Workbox-Build- ,
Workbox-Cli- und
Workbox-Webpack-Plugin-Pakete (sie können sogar den gesamten Service Worker-Code generieren).
Mein
Demo- Projekt enthält ein Beispiel für die Implementierung des vorläufigen Caching mithilfe eines Servicemitarbeiters in einer
Rollup-Anwendung (mithilfe von
workbox-cli
) und in einer
Webpack-Anwendung (mithilfe von
workbox-webpack-plugin
).
Ansatz 3: Benutzerdefinierte Skripte zum Laden von Ressourcen
Wenn Ihre Site weder Importkarten noch Servicemitarbeiter verwenden kann, finden Sie hier den dritten Ansatz zur Lösung des Problems. Es besteht darin, die Funktionalität des Importierens von Karten mithilfe eines eigenen Skripts zum Laden von Ressourcen zu implementieren.
Wenn Sie mit
Modulladern im AMD-Stil (wie
SystemJS oder
RequireJS ) vertraut sind, wissen Sie möglicherweise auch, dass diese
Modullader normalerweise Modulaliasnamen unterstützen. Tatsächlich
unterstützt SystemJS Aliasing mithilfe der Importzuordnungssyntax. Infolgedessen lässt sich unser Problem leicht so lösen, dass diese Lösung zukunftsorientiert ist (und außerdem in allen vorhandenen Browsern funktioniert).
Wenn Sie Rollup verwenden, können Sie die Option
output.format auf
system
. In diesem Fall wird das Erstellen einer Importzuordnung für die Anwendung auf die gleiche Weise durchgeführt, wie in der Beschreibung des ersten Ansatzes zur Lösung des Problems der kaskadierenden Cache-Ungültigkeit beschrieben.
Meine Demoanwendung verfügt über eine Beispielsite, auf der
Rollup zum Erstellen von Materialien in einem für SystemJS geeigneten Format und zum Erstellen einer Importzuordnung zum Herunterladen von Hash-Versionen von Dateien verwendet wird.
▍Webpacken und Laden von Ressourcen mithilfe von Skripten
Webpack kann Ihnen auch beim Laden von Ressourcen mithilfe Ihres eigenen Skripts helfen. Der von Webpack generierte Loader ist jedoch im Gegensatz zu den klassischen AMD-Loadern für jedes spezifische Bundle einzigartig.
Der Vorteil dieses Ansatzes besteht darin, dass die Webpack-Laufzeit (und damit funktioniert sie tatsächlich) eigene Zuordnungen zwischen den Namen / Bezeichnern der Fragmente und ihren Adressen enthalten kann (dies ähnelt dem, was ich hier empfehle). Dies bedeutet, dass Webpack-Bundles, die Codeaufteilung verwenden, weniger wahrscheinlich eine kaskadierende Cache-Ungültigkeit erleiden.
Die gute Nachricht für Webpack-Benutzer ist, dass eine Änderung des Codes eines einzelnen Moduls nicht zu einer Ungültigmachung führen sollte, wenn sie die Projektassembly mithilfe von Webpack korrekt konfiguriert haben (Aufteilen des Codes in Fragmente, wie im Webpack-Caching-
Handbuch beschrieben ) mehr als zwei Fragmente (eines enthält das modifizierte Modul, das zweite enthält die Laufzeit).
Aber ich habe einige schlechte Nachrichten für diejenigen, die Webpack verwenden, um Projekte zu erstellen. Tatsache ist, dass das interne Mapping-System dieses Bundlers nicht dem Standard entspricht. Dies bedeutet, dass es nicht in vorhandene Tools integriert werden kann und dass der Benutzer es nicht konfigurieren kann. Sie können beispielsweise keine Ausgabedateien unabhängig generieren (dh wie in der Geschichte über den ersten Ansatz zur Lösung des Problems beschrieben) und keine eigenen Hashes in das Mapping einfügen. Dies ist ein Minus des Webpacks, da die von diesem Bundler verwendeten Hashes
nicht auf dem Inhalt der Ausgabedateien basieren, sondern auf dem Inhalt der Quelldateien und der Build-Konfiguration. Und dies kann zu kleinen und subtilen Fehlern führen (zum Beispiel -
hier ,
hier und
hier - Meldungen über solche Fehler).
Wenn Sie Webpack verwenden, um eine Anwendung zu erstellen, die auch einen Servicemitarbeiter verwendet, würde ich die Verwendung der
Workbox-Webpack-Plugin- und Caching-Strategie empfehlen, die im zweiten Ansatz zur Lösung des Problems beschrieben wurde. Das Plugin generiert Hashes basierend auf dem Inhalt der Webpack-Ausgabe. Sie müssen sich also keine Gedanken über die oben genannten Fehler machen. Darüber hinaus ist das Arbeiten mit Dateinamen ohne Hashes normalerweise einfacher als das Arbeiten mit Namen ohne Hashes.
Andere Webprojektressourcen
Zuvor habe ich darüber gesprochen, wie die Arbeit in JavaScript-Programmen mit "gehashten" Dateinamen, die Programmcode enthalten, zu einer kaskadierenden Cache-Ungültigkeit führen kann. Dieses Problem betrifft jedoch auch andere Webprojektmaterialien.
Daher verweisen CSS- und SVG-Dateien häufig auf andere Ressourcen (z. B. Bilder), deren Namen Informationen zu den Versionen der entsprechenden Dateien in Form von Hashes enthalten können. Wie bei JS-Dateien können Sie Importkarten oder Servicemitarbeiter verwenden, um das Problem der Kaskadierung der Cache-Ungültigkeit zu lösen, die durch Änderungen der Namen ähnlicher Ressourcen verursacht wird.
Für Ressourcen wie Bilder und Videodateien ist dies kein Problem. Hier gelten alle bestehenden Empfehlungen.
Die Hauptsache hierbei ist, sich daran zu erinnern, dass immer dann, wenn Datei A Datei B herunterlädt und zusätzlich Informationen über die Version von Datei B als Hash ihres Inhalts enthält, die Ungültigmachung des Caches für Datei B auch eine Ungültigmachung des Caches für Datei A verursacht. Wenn Sie mit Ressourcen arbeiten, deren Verwendung unterschiedlich organisiert ist, können Sie die in diesem Material gegebenen Ratschläge einfach ignorieren.
Zusammenfassung
Ich hoffe, dieser Artikel hat Sie dazu inspiriert, sich Ihre Website genauer anzusehen und herauszufinden, ob sich das Problem der kaskadierenden Cache-Ungültigkeit darauf auswirkt. Der einfachste Weg, dies zu überprüfen, besteht darin, die Site zusammenzustellen, eine Codezeile in einer Datei zu ändern, die von vielen Modulen importiert wird, und dann die Site neu zu erstellen. Wenn sich in dem Verzeichnis, in dem sich die Assembly-Ergebnisse befinden, die Namen für mehr als eine Datei geändert haben, bedeutet dies, dass Sie ein Zeichen für eine kaskadierende Cache-Ungültigkeit haben. In diesem Fall müssen Sie möglicherweise über einen der hier beschriebenen Ansätze nachdenken, um dieses Problem in Ihrem Projekt zu lösen.
Wenn wir darüber sprechen, was besser zu wählen ist, dann hängt es ehrlich gesagt von vielem ab.
Wenn Importkarten von Browsern weitgehend unterstützt werden, haben wir die einfachste und perfekteste Möglichkeit, mit der Kaskadierung der Cache-Ungültigkeit umzugehen. Bis eine solche Unterstützung verfügbar ist, ist dieser Mechanismus in der Praxis nicht anwendbar.
Wenn Sie bereits Servicemitarbeiter einsetzen, insbesondere wenn Sie Workbox verwenden, würde ich den zweiten Ansatz zur Lösung des hier beschriebenen Problems empfehlen. Auf der
Site, auf der das Original dieses Materials veröffentlicht wird, wurde die Aufgabe des vorläufigen Zwischenspeicherns von Ressourcen auf diese Weise gelöst.
Darüber hinaus sind Servicemitarbeiter die einzige Option für diejenigen, die
JavaScript-Module in der Produktion verwenden. (Angesichts der Tatsache, dass 98% meiner Benutzer Browser haben, die sowohl Servicemitarbeiter als auch JS-Module unterstützen, war es für mich nicht schwierig, diese Option zu wählen.)
Wenn Servicemitarbeiter nicht für Sie geeignet sind, würde ich den dritten der hier diskutierten Ansätze empfehlen, der die Verwendung von SystemJS beinhaltet. Dieser Ansatz ist besser als andere, basierend auf Bootloader-Skripten, die auf die Zukunft ausgerichtet sind. Von dort aus können Sie problemlos zu Importkarten wechseln, wenn deren Unterstützung in allen Browsern angezeigt wird.
Wenn wir über Produktivität sprechen, hängt die Wahl der Richtung der Optimierung von jedem spezifischen Projekt ab. Vor der Optimierung der Leistung ist es wichtig, diese zu messen und dann zu entscheiden, ob ein Problem vorliegt und ob es bekämpft werden soll. Wenn Sie selten neue Projektversionen veröffentlichen und die am Projekt vorgenommenen Änderungen normalerweise recht umfangreich sind, ist das Problem der Kaskadierung der Cache-Ungültigmachung für Sie möglicherweise nicht relevant.
Wenn Sie jedoch häufig kleine Projektänderungen bereitstellen, können Ihre wiederkehrenden Benutzer auf das Problem stoßen, große Mengen an Code zu laden, die bereits in ihren Caches vorhanden sind. Die Lösung dieses Problems bedeutet für diese Benutzer eine erhebliche Steigerung der Leistung beim Laden von Seiten.
Liebe Leser! Beeinflusst die kaskadierende Cache-Ungültigmachung Ihr Projekt? Wenn ja, teilen Sie uns bitte mit, wie Sie das Problem lösen möchten.
