Reputation: 967
I've recently started to delve into service workers and the related strategies. There seems to be some confusion in my mind, or if I'm understanding them correctly, something of a flaw in the entire API — the issue being that when you make a change to your serviceworker.js
file (i.e. change a version number in this file because you've made changes to your website), the user has to then visit the site twice to see the changes? Once to register and install the new service worker, and a second time to activate it (i.e access the new cache).
Now in the real world if there is an issue on your site, whether it be broken link, a javascript error, or the wrong info in a blog post etc, when a user comes back to that site for the first after you've made the fix, there's no way of them seeing this fix unless they come back a second time? Even though you've made the changes?
I mean, this can't be true...surely?
CODE THAT I'M USING
var preCacheList = [
"/", "index.html", "work.html", "contact.html", "style.css", "js/main.js"
];
var CACHE_STATIC_NAME = 'static-v1.4';
var CACHE_DYNAMIC_NAME = 'dynamic-v1.4';
self.addEventListener('install', function(event) {
console.log('[Service Worker] Installing Service Worker ...', event);
event.waitUntil(
caches.open(CACHE_STATIC_NAME)
.then(function(cache) {
console.log('[Service Worker] Precaching App Shell');
cache.addAll(preCacheList);
})
)
});
self.addEventListener('activate', function(event) {
console.log('[Service Worker] Activating Service Worker ....', event);
event.waitUntil(
caches.keys()
.then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
console.log('[Service Worker] Removing old cache.', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
} else {
return fetch(event.request)
.then(function(res) {
return caches.open(CACHE_DYNAMIC_NAME)
.then(function(cache) {
cache.put(event.request.url, res.clone());
return res;
})
})
.catch(function(err) {
});
}
})
);
});
Upvotes: 4
Views: 1887
Reputation: 967
I found the solution to this — you need to add the skipWaiting()
method in the initial installation event.
I've re-posted the code from my question above with a comment on this line:
var preCacheList = [
"/", "index.html", "work.html", "contact.html", "style.css", "js/main.js"
];
var CACHE_STATIC_NAME = 'static-v1.4';
var CACHE_DYNAMIC_NAME = 'dynamic-v1.4';
self.addEventListener('install', function(event) {
console.log('[Service Worker] Installing Service Worker ...', event);
event.waitUntil(
caches.open(CACHE_STATIC_NAME)
.then(function(cache) {
console.log('[Service Worker] Precaching App Shell');
cache.addAll(preCacheList);
})
)
return self.skipWaiting(); // THIS IS THE LINE THAT OVER-RIDES THE SECOND RELOAD.
});
self.addEventListener('activate', function(event) {
console.log('[Service Worker] Activating Service Worker ....', event);
event.waitUntil(
caches.keys()
.then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) {
console.log('[Service Worker] Removing old cache.', key);
return caches.delete(key);
}
}));
})
);
return self.clients.claim();
});
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
} else {
return fetch(event.request)
.then(function(res) {
return caches.open(CACHE_DYNAMIC_NAME)
.then(function(cache) {
cache.put(event.request.url, res.clone());
return res;
})
})
.catch(function(err) {
});
}
})
);
});
Upvotes: 1