How to clear cache of service worker?

96,654

Solution 1

Use this to delete outdated caches:

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          // Return true if you want to remove this cache,
          // but remember that caches are shared across
          // the whole origin
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
});

Solution 2

If you know the cache name you can simply call caches.delete() from anywhere you like in the worker:

caches.delete(/*name*/);

And if you wanted to wipe all caches (and not wait for them, say this is a background task) you only need to add this:

caches.keys().then(function(names) {
    for (let name of names)
        caches.delete(name);
});

Solution 3

Typically you update the CACHE_NAME in your service workers JS file so your worker installs again:

self.addEventListener('install', evt => {
  evt.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(inputs))
  )
})

Alternatively, to clear the cache for a PWA find the cache name:

self.caches.keys().then(keys => { keys.forEach(key => console.log(key)) })

then run the following to delete it:

self.caches.delete('my-site-cache')

Then refresh the page.

If you see any worker-related errors in the console after refreshing, you may also need to unregister the registered workers:

navigator.serviceWorker.getRegistrations()
  .then(registrations => {
    registrations.forEach(registration => {
      registration.unregister()
    }) 
  })

Solution 4

The most elegant solution, with async/await:

const cacheName = 'v2';

self.addEventListener('activate', event => {
// Remove old caches
  event.waitUntil(
    (async () => {
      const keys = await caches.keys();
      return keys.map(async (cache) => {
        if(cache !== cacheName) {
          console.log('Service Worker: Removing old cache: '+cache);
          return await caches.delete(cache);
        }
      })
    })()
  )
})

Solution 5

This is the only code that worked for me. It is my adaptation of Mozilla documentation :

//Delete all caches and keep only one
const cachNameToKeep = 'myCache';

//Deletion should only occur at the activate event
self.addEventListener('activate', event => {
    var cacheKeeplist = [cacheName];
    event.waitUntil(
        caches.keys().then( keyList => {
            return Promise.all(keyList.map( key => {
                if (cacheKeeplist.indexOf(key) === -1) {
                    return caches.delete(key);
                }
            }));
        })
.then(self.clients.claim())); //this line is important in some contexts
});
Share:
96,654
taek
Author by

taek

Updated on March 18, 2021

Comments

  • taek
    taek about 3 years

    So, I have an HTML page with service worker, the service worker cache the index.html and my JS files.

    The problem is when I change the JS, the change doesn't show up directly on the client browser. Of course in chrome dev-tools, I can disable cache. But in chrome mobile, how do I do that?

    I tried to access the site settings and hit the CLEAR % RESET button. But it still loads the old page/load from cache. I tried to use other browser or chrome incognito and it loads the new page.

    Then, I try to clear my browsing data (just cache) and it works.

    I guess that's not how it should work right? my user won't know if the page is updated without clearing the chrome browser cache.

  • loopmode
    loopmode over 6 years
    What is self here? The window object or a serviceworker?
  • Samuel Liew
    Samuel Liew over 6 years
    It's good practice on Stack Overflow to add an explanation as to why your solution should work. For more information read How To Answer.
  • elf
    elf over 6 years
    Thanks for this. It is a lot simpler a clearer. I just wrote mine up quickly to answer the question
  • Hashbrown
    Hashbrown over 6 years
    Nah no worries. Yours would be perfect if someone wanted to delete a specific set of caches within the activate listener; I just did this in case someone only wanted to dump one/everything
  • Pat Mächler
    Pat Mächler over 6 years
    The most compact code is probably caches.keys().then(cs=>cs.forEach(c=>caches.delete(c))) or for async functions (await caches.keys()).forEach(c=>caches.delete(c))
  • Khaledonia
    Khaledonia over 6 years
    where I live, You Mr. will be regarded a Mustache ! ( a compliment )
  • Sunjoong Kevin Kim
    Sunjoong Kevin Kim about 6 years
    self means serviceWorker instance. :)
  • Nux
    Nux about 6 years
    Note! You should check if caches exists. If you want to clear caches outside of the Service Worker check add something like if (!window.caches) return;. Also not that caches object might not exist on HTTP (e.g. in Chrome).
  • renardesque
    renardesque almost 6 years
    self is a "SharedWorkerGlobalScope" object.
  • zipzit
    zipzit over 4 years
    cacheNameToKeep ?? [cacheName] ?? Are those both the same thing? What does self.clients.claim() do?
  • Vitalij
    Vitalij about 4 years
    last code: "navigator.serviceWorker....." helped me after removing superpwa wordpress plugin, to delete all cache related to service worker. Thanks
  • Evading Shadows
    Evading Shadows about 4 years
    Using 'this' instead of 'self' can do the same same thing. But there's a difference between these two keywords.
  • David
    David almost 4 years
    Are the descriptive words above your code blocks 2 and 3 swapped?
  • vhs
    vhs over 3 years
    Thanks, David. Fixed with your help.
  • Esteban Ortega
    Esteban Ortega about 3 years
    The service worker is installed in your browser. Your browser will request your remote worker every time (if online) and update its locally installed version for offline use. You can see which files get cached by printing it to console, i.e. console.log('Caching:', event.request.url) in your 'fetch' event after cache.put()
  • Adam Youngers
    Adam Youngers about 3 years
    How would one accomplish this using GenerateSW()? For my purposes, reseting all caches on publish of a new service worker would be ideal.
  • Adam Youngers
    Adam Youngers about 3 years
    @Hashbrown - Is there a way to accomplish this using Workbox's GenerateSW()? For my purposes, reseting all caches on publish of a new service worker would be ideal.