Valentin
Valentin

Reputation: 415

PWA Cache refresh page

I have a problem with the pwa of my website. I need to update the cache memory with the service worker and I find many codes on the internet but none works. I have to miss something.

I wish that after a simple reload of the page the update is done, likewise when we click on the shortcut of the PWA that everything is updated automatically. Here is my manifest and my service worker with the code I use.

What do you think ?

thank you in advance

//Manifest -----

{
  "name": "Test",
  "short_name": "Test",
  "lang": "en",
  "start_url": "./index.html",
  "display": "standalone",
  "background_color": "white",
  "theme_color": "white",
  "icons": [{
      "src": "/img/icon-128.png",
        "sizes": "128x128",
        "type": "image/png"
      }, {
        "src": "/img/icon-144.png",
        "sizes": "144x144",
        "type": "image/png"
      }, {
        "src": "/img/icon-152.png",
        "sizes": "152x152",
        "type": "image/png"
      }, {
        "src": "/img/icon-192.png",
        "sizes": "192x192",
        "type": "image/png"
      }, {
        "src": "/img/icon-256.png",
        "sizes": "256x256",
        "type": "image/png"
      }, {
        "src": "/img/icon-512.png",
        "sizes": "512x512",
        "type": "image/png"
      }]
}

-

//Service-Worker -----

var cacheName = 'Test';
var filesToCache = [
  '/',
  '/index.html',
  '/css/style.css',
   ...
];

/* Start the service worker and cache all of the app's content */
self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(filesToCache);
    })
  );
});

/* Serve cached content when offline */
self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

self.addEventListener('activate', function(event) {
  var cacheKeeplist = ['cacheName'];

  event.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (cacheKeeplist.indexOf(key) === -1) {
          return caches.delete(key);
        }
      }));
    })
  );
});

Upvotes: 3

Views: 16732

Answers (1)

pate
pate

Reputation: 5263

The problem is very simple: your Service Worker code is not updating the cache.

If you look at the fetch handler, it either returns a response from the cache or from the network. And if it returns the response from the network, it does NOT put the new version into the cache.

If you look at the install handler, it caches all the files listed. Those files (at least it seems so) are all named so that the names stay the same from version to another. Meaning: your style.css is always style.css and when the SW has cached it, it will be happy with the cached version 'til the end of time. It does not have any idea that there's a new version because the name is the same.

How to fix this?

You can amend the SW code so that it always checks the network for new updates to the files (examples here: https://serviceworke.rs/strategy-cache-and-update.html). You might also like to have unique names for files that change on every deploy.

Another way could be to use a library that handles all of this for you. Workbox has multiple different caching strategies to choose from (https://developers.google.com/web/tools/workbox/modules/workbox-strategies).

EDIT: How to update the app that was added to homescreen?

I'm not entirely sure why your added-to-the-homescreen app doesn't update when you open it again. It might be running some older version that has still got an older version of this or that. However, you can manually force the Service Worker to check for updates. You can use registration.update() to trigger a check for a new version of SW script, and if found, force refresh the page (location.reload()) or show the user a notification and ask for refresh. Documentation here: https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update

If you have an app that the user keeps open for a long time (in mobile or in a browser tab), it might be nice to poll for SW updates automatically eg. once a day or something. You could even check for updates every time the tab/app is activated/focused. Frequence of course depends on your app, use case etc. :)

Upvotes: 8

Related Questions