Reputation: 81
I am using a ServiceWorker to precache files. The serviceworker.js is generated whenever I build the application, and all files newer than the last version of serviceworker.js are added to the file as an array, as well as the current timestamp, so if I modify a cached file it is added to the cache and the timestamp changes, so the serviceworker is reinstalled. In the install event handler, I delete the new files then add them:
newFiles.forEach((resource) => {
cache.delete(resource)
.then(() => { })
.catch((error) => { console.warn(`${resource}: ${error}`); });
});
newFiles.forEach((resource) => {
cache.add(resource)
.then(() => { })
.catch((error) => { console.warn(`${resource}: ${error}`); });
}
I claim the clients:
self.addEventListener('activate', (event) => {
event.waitUntil(clients.claim())});
I can see the correct timestamp for the file in my cache:
In the serviceworker, I log cache hits:
/css/main.css cached
Unfortunately, the page renders with the previous version of main.css. If I do a hard reload, I get the page rendered with the new css, but if I then do a regular reload, the old css comes back. Requesting the file with curl gets the new version. So it seems the cached file is retained. I know that I can delete the entire cache, and I know I can change the name of the file to main-datestamp.css, but this seems inelegant. What am I missing?
Upvotes: 0
Views: 20
Reputation: 81
The problem was that I have 2 versions of the program; demo and production; these run at different URLs. I cache more files in demo, so I had demo-cache for https://demo.example.com and production-cache for https://production.example.com. So when I updated the css file in demo-cache, it still found it in production-cache because I was reading from all caches:
const responseFromCache = await caches.match(request);
I changed this to:
const responseFromCache = await caches.match(request,{'cacheName': 'demo-cache'});
Also, the cache.delete is unnecessary. So how do we handle someone deleting the cache? Since we have a complete list of resources, we just use Set operations:
cache.keys().then((keys) => {
const resourceSet = new Set(myresources);
const cacheSet = new Set(keys);
const difference = resourceSet.difference(cacheSet);
const newfilesSet = new Set(newFiles).union(difference);
newfilesSet.forEach((resource) => {
cache.add(resource)
.then(() => { })
.catch((error) => { console.warn(`${resource}: ${error}`); });
})
})
Note that the intent of this code is to cache a limited number of files, in my case images and audio files that are required for animations.
Upvotes: 0