Start · Sprachen · JavaScript · Referenz · WorkerGlobalScope.caches

WorkerGlobalScope.caches

Eigenschaft

Schreibgeschützte Eigenschaft, die im Worker-Kontext das zugehörige <code>CacheStorage</code>-Objekt liefert, über das sich benannte <code>Cache</code>-Objekte verwalten lassen.

seit JavaScript Baseline: alle modernen Browser (seit ca. 2018); n Kategorie: webapi

Signatur

WorkerGlobalScope.caches

Beschreibung

Die Eigenschaft caches ist in jedem Worker-Kontext verfügbar, also in Service Workern, Dedicated Workern und Shared Workern. Sie gibt das CacheStorage-Objekt zurück, das dem Ursprung (Origin) des Workers zugeordnet ist. Im Worker schreibt man sie meist ohne Präfix als globales caches oder als self.caches.

Über CacheStorage öffnet, durchsucht und löscht man benannte Caches (caches.open(), caches.match(), caches.keys(), caches.delete()). Jeder Cache speichert Paare aus Request und Response. So lassen sich Offline-Fähigkeit, Precaching beim install-Event und Strategien wie „Cache zuerst“ oder „Netzwerk zuerst“ im fetch-Handler eines Service Workers umsetzen.

Der Speicher ist derselbe wie bei window.caches im Hauptthread desselben Ursprungs. Daten, die ein Service Worker ablegt, kann die Seite also direkt lesen, und umgekehrt. Alle Methoden arbeiten asynchron und liefern Promises. Deshalb eignet sich die API gut für async/await.

Rückgabewert

Typ
CacheStorage
Beschreibung
Das CacheStorage-Objekt des aktuellen Ursprungs. Die Eigenschaft ist schreibgeschützt.

Beispiele

Precaching beim install-Event eines Service Workers

// sw.js
const CACHE_NAME = 'app-v1';
const ASSETS = ['/', '/index.html', '/styles.css', '/app.js'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    (async () => {
      const cache = await caches.open(CACHE_NAME);
      await cache.addAll(ASSETS);
      console.log('Assets vorab gecacht:', ASSETS.length);
    })()
  );
});
Assets vorab gecacht: 4

Strategie „Cache zuerst, sonst Netzwerk“ im fetch-Handler

self.addEventListener('fetch', (event) => {
  if (event.request.method !== 'GET') return;

  event.respondWith(
    (async () => {
      const cached = await caches.match(event.request);
      if (cached) return cached;

      const response = await fetch(event.request);
      // Nur erfolgreiche, eigene Antworten zwischenspeichern
      if (response.ok && response.type === 'basic') {
        const cache = await caches.open('runtime-v1');
        await cache.put(event.request, response.clone());
      }
      return response;
    })()
  );
});

Veraltete Caches beim activate-Event aufräumen

const AKTUELL = ['app-v2', 'runtime-v1'];

self.addEventListener('activate', (event) => {
  event.waitUntil(
    (async () => {
      const namen = await caches.keys();
      const alt = namen.filter((name) => !AKTUELL.includes(name));
      await Promise.all(alt.map((name) => caches.delete(name)));
      console.log('Gelöscht:', alt);
    })()
  );
});
Gelöscht: ["app-v1"]

Nutzung in einem Dedicated Worker

// worker.js
self.addEventListener('message', async ({ data }) => {
  if (!('caches' in self)) {
    self.postMessage({ fehler: 'CacheStorage nicht verfügbar' });
    return;
  }
  const cache = await caches.open('daten-v1');
  let res = await cache.match(data.url);
  if (!res) {
    res = await fetch(data.url);
    await cache.put(data.url, res.clone());
  }
  self.postMessage(await res.json());
});

// Wichtig · Fallstricke

  • Nur in sicheren Kontexten: Die Eigenschaft gibt es nur unter HTTPS oder localhost. Unter HTTP ist caches undefined. Deshalb vor der Nutzung mit 'caches' in self prüfen.
  • Response nur einmal lesbar: Der Körper einer Response lässt sich nur einmal auslesen. Wer eine Antwort zurückgibt und zugleich cachen will, muss sie mit response.clone() kopieren.
  • Keine automatische Ablaufzeit: Die Cache-API beachtet keine HTTP-Caching-Header. Einträge bleiben erhalten, bis man sie selbst löscht. Caches deshalb versionieren und im activate-Event aufräumen.
  • Speicherkontingent: Der Browser kann den Speicher bei Platzmangel räumen. Mit navigator.storage.persist() lässt sich dauerhafter Speicher anfordern, und navigator.storage.estimate() zeigt den Verbrauch.
  • cache.put() lehnt Nicht-GET-Anfragen ab. Opake Antworten (type: 'opaque') haben den Status 0 und belegen viel vom Kontingent.
  • Im privaten Modus mancher Browser (z. B. Firefox) kann caches fehlen oder Fehler werfen.