Recently this problem appeared in our pwa. I had all default settings in workbox pwa module and everything worked fine, but now it seems root page (/) is precached, it is exists in CacheStorage workbox-precache-v2-...
After unregistering manually service worker this problem is gone, but only for the time before next page reload.
I can solve issue by manually deleting this CacheStorage, but it's not the solution because our users won't do it manually.
Question is, by which way sw can force delete this cache for all users ? Or is there a way to disable precache of this page? Maybe there is another way to solve this?
Also we have cloudflare cache, could it be a problem?
Also have this warning: Workbox is precaching URLs without revision info: / but updated pwa-module to the latest version.
I also encountered this problem.
I've read through source code and I don't think it's possible to fix it by ourselves - array of precached resources is built from webmanifest config and some defaults, which include / route.
Google docs say, that cache-first policy is used for precached resources, that's why page is not refreshed.
Precached resources are updated once service worker is, only if revision changes. And because no revision is used, it's not updating.
Maybe some randomized revision would help?
Problem is, that we may get some non-deterministic behavior - service worker is not updated immadietely, when you open the page. It may take some time, especially if you have other tabs open, that it controls. So you would get the old version until the service worker is running.
It would be nice to be able to fine-tune precaching, so we'd be able to remove / from precached resources.
Exactly the problem is because of / pushed to precache array. Currently there is no way to remove it. It must be fixed.
Ok guys, I have some temporary solution for ya!
Do not change default start_url in pwa.manifest:
pwa: {
manifest: {
orientation: 'portrait-primary',
background_color: '#ffffff',
theme_color: '#010101',
start_url: '/', // <- this breaks the thing for me
display: 'browser',
},
},
By default it's /?standalone=true and that's good for you, because /?standalone=true will be precached, and not /.
I tried the fix proposed by @kedrzu which works for the start_url. It does not seem to clear the precache for the offlinePage template, which is a smaller issue but an issue still.
I created a PR with proposed fix, but it's not merged yet. In my own project I created my own sw.template.js file:
const options = <%= JSON.stringify(options.swOptions) %>
importScripts(...[options.workboxURL, ...options.importScripts])
initWorkbox(workbox, options)
workboxExtensions(workbox, options)
cachingExtensions(workbox, options)
runtimeCaching(workbox, options)
offlinePage(workbox, options)
routingExtensions(workbox, options)
function getProp(obj, prop) {
return prop.split('.').reduce((p, c) => p[c], obj)
}
function initWorkbox(workbox, options) {
if (options.config) {
// Set workbox config
workbox.setConfig(options.config)
}
if (options.cacheNames) {
// Set workbox cache names
workbox.core.setCacheNameDetails(options.cacheNames)
}
if (options.clientsClaim) {
// Start controlling any existing clients as soon as it activates
workbox.core.clientsClaim()
}
if (options.skipWaiting) {
workbox.core.skipWaiting()
}
if (options.cleanupOutdatedCaches) {
workbox.precaching.cleanupOutdatedCaches()
}
if (options.offlineAnalytics) {
// Enable offline Google Analytics tracking
workbox.googleAnalytics.initialize()
}
}
function runtimeCaching(workbox, options) {
for (const entry of options.runtimeCaching) {
const urlPattern = new RegExp(entry.urlPattern)
const method = entry.method || 'GET'
const plugins = (entry.strategyPlugins || [])
.map(p => new (getProp(workbox, p.use))(...p.config))
const strategyOptions = { ...entry.strategyOptions, plugins }
const strategy = new workbox.strategies[entry.handler](strategyOptions)
workbox.routing.registerRoute(urlPattern, strategy, method)
}
}
function offlinePage(workbox, options) {
if (options.offlinePage) {
// Register router handler for offlinePage
workbox.routing.registerRoute(new RegExp(options.pagesURLPattern), ({ request, event }) => {
const strategy = new workbox.strategies[options.offlineStrategy]
return strategy
.handle({ request, event })
.catch(() => caches.match(options.offlinePage))
})
}
}
function workboxExtensions(workbox, options) {
<%= options.workboxExtensions %>
}
function cachingExtensions(workbox, options) {
<%= options.cachingExtensions %>
}
function routingExtensions(workbox, options) {
<%= options.routingExtensions %>
}
It's exactly same as original https://github.com/nuxt-community/pwa-module/blob/master/lib/workbox/templates/sw.js, but it lacks the part responsible for precaching.
Then added in config:
workbox: {
swTemplate: './sw.template.js',
// other settings
}
Seems to be caused when trying to fix this issue: https://github.com/nuxt-community/pwa-module/issues/372
I used this code on the loading screen as a workaround (unregister service worker and hard reload to use new serviceWorker):
function reloadApp() {
if (window.location.hash !== '#retry') {
window.location.hash = '#retry';
window.location.reload(true);
} else {
/* Workaround failed, inform user */
setLoadingMessage('An error occurred');
}
}
window.addEventListener('error', function (event) {
if ('serviceWorker' in navigator) {
/* Prepare for unregister serviceWorker and reload, inform user */
setLoadingMessage('Updating...');
navigator.serviceWorker.getRegistrations().then(function(registrations) {
registrations.forEach(function(r) {
r.unregister();
});
reloadApp();
});
} else {
/* Could not try workaround, inform user */
setLoadingMessage('An error occurred');
}
});
setLoadingMessage() just updates the UI.
Hi. This issue should be gone with 3.3.0.
There is yet one more known issue tracking here: #406
Most helpful comment
I also encountered this problem.
I've read through source code and I don't think it's possible to fix it by ourselves - array of precached resources is built from webmanifest config and some defaults, which include
/route.Google docs say, that
cache-firstpolicy is used for precached resources, that's why page is not refreshed.Precached resources are updated once service worker is, only if revision changes. And because no revision is used, it's not updating.
Maybe some randomized revision would help?
Problem is, that we may get some non-deterministic behavior - service worker is not updated immadietely, when you open the page. It may take some time, especially if you have other tabs open, that it controls. So you would get the old version until the service worker is running.
It would be nice to be able to fine-tune precaching, so we'd be able to remove
/from precached resources.