Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update service worker cache in PWA?

I use service worker with sw-toolbox library. My PWA caches everything except API queries (images, css, js, html). But what if some files will be changed someday. Or what if service-worker.js will be changed. How application should know about changes in files?

My service-worker.js:

'use strict';
importScripts('./build/sw-toolbox.js');

self.toolbox.options.cache = {
  name: 'ionic-cache'
};

// pre-cache our key assets
self.toolbox.precache(
  [
    './build/main.js',
    './build/main.css',
    './build/polyfills.js',
    'index.html',
    'manifest.json'
  ]
);

// dynamically cache any other local assets
self.toolbox.router.any('/*', self.toolbox.cacheFirst);

// for any other requests go to the network, cache,
// and then only use that cached resource if your user goes offline
self.toolbox.router.default = self.toolbox.networkFirst;

I don't know what is the usual method to update cache in PWA. Maybe PWA should send AJAX request in background and check UI version?

like image 399
Ildar Avatar asked Jun 19 '17 10:06

Ildar


People also ask

What is cache in PWA?

A PWA can store assets on your device any time after the first visit in the browser, even without installation. Install is a separate action that is covered later in this course. The Cache Storage API is available from different contexts: The window context (your PWA's main thread).

Where is Serviceworker cache stored?

Note that this is NOT the Cache folder. It's the Cache of Service Worker, the path should be AppData\Local\Microsoft\Edge\User Data\Default\Service Worker .

Does PWA use service workers?

Service workers are a fundamental part of a PWA. They enable fast loading (regardless of the network), offline access, push notifications, and other capabilities.


4 Answers

AFAIK the sw_toolbox does not have a strategy for cache with network update. This is really what you want I think. You want to modify the cache-network race strategy - > https://jakearchibald.com/2014/offline-cookbook/#cache-network-race Instead of just letting the loser fade away, once the network responds you will want to update the client. This is a little more advanced that I have time or time to explain here. I would post a message to the client to let it know there is an update. You may want to alert the user to the update or just force the update. I don't consider this to be an edge case, but a very common, but advanced scenario. I hope to publish a more detailed solution soon.

like image 77
Chris Love Avatar answered Oct 02 '22 13:10

Chris Love


There is nice solution written here where he states (in a nutshell) to either not use cache-first strategy or update a UX pattern of displaying a "Reload for the latest updates."

like image 23
oninross Avatar answered Oct 02 '22 14:10

oninross


I dealt with services workers without using any library and the solution I ended up coming up with involved a bit of server side code and some client side. The strategy in a nutshell

Firstly the variables you will need and where:

  1. On the server side have a "service worker version" variable (Put this in a database or config file if you are using something like php that will update immediately on the server side without requiring a redeploy. Let's call it serverSWVersion
  2. On one of the javascript files you cache (I have a javascript file dedicated to this) have a global variable that will also be the "service worker version". Let's call it clientSWVersion

Now how to use the two:

  1. Whenever a person lands on the page make an ajax call to your server to get the serverSWVersion value. Compare this with the clientSWVersion value.

  2. If the values are different that means your web app version is not the latest.

  3. If this is the case then unregister the service worker and refresh the page so that the service worker will be re registered and the new files will be cached.

What to actually do when new file is available

  1. Update the serviceSWVersion and clientSWVersion variables and upload to server where applicable.

  2. When a person visits again then the service worker should be re registered and all the cached files will be retrieved.

I have provided a php server side based code that I used while I was implementing this strategy. It should show you the principles. Just drop the "Exercise" folder in a htdocs of a php server and it should work without you having to do anything else. I hope you find it useful... And remember you could just use a database instead of a config file to store the server side service worker variable if you are using some other server instead of php:

Zip file with code: ServiceWorkerExercise.zip

like image 31
Zuks Avatar answered Oct 02 '22 13:10

Zuks


When a service worker is altered, the browser will install it, but the new version will not be activated until the browser tab or PWA app window is closed and re-opened. So, if you change the cache name, the new cache will not serve any files until the browser re-opens, nor will the old cache be deleted until that time. You can detect service worker changes in your page javascript using registration.onupdatefound and ask the user to close and re-open the window - something like this:

// register the service worker
	navigator.serviceWorker.register('sw.js').then(function(registration) 
	{
		registration.onupdatefound = function()
		{
			console.log("ServiceWorker update found.");
			alert("A new version is available - please close this browser tab or app window and re-open to update ... ");
		}
	}, function(err)
	{
		console.log('ServiceWorker registration failed: ', err);
	});
like image 30
Craig Avatar answered Oct 02 '22 12:10

Craig