Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I cache the ServiceWorker file in a PWA?

I still struggle how to avoid caching problems in Progressive Web Apps. Crucial for any PWA caching is the ability to update the ServiceWorker file (let's call it sw.js). But the details are a bit confusing to me:

  • It's okay to execute navigator.serviceWorker.register('sw.js') on every page load because register() updates the app cache or does nothing if everything is up to date -- correct?

  • Does it make sense to do something like navigator.serviceWorker.register('sw.js?' + Date.now()) to avoid HTTP caching? Or am I on the safe side if the server uses ETags?

  • Does the browser check the network for an updated sw.js on every pageload? I sometimes don't see it in the network inspector tab.

  • If sw.js is in the app cache, does the browser fetch it from there without checking the server for an update?

  • I sometimes see ServiceWorker demo scripts that cache themselves like this:

    self.addEventListener('install', ev => {
        const myCaches = {
            app: {...}, 
            sw: {
                files: [
                    '/sw.js'
                ],
                version: '1'
            }
        }
        for (let name in myCaches) {
            const cacheName = name + '-' + myCaches[name].version
            ev.waitUntil(
                caches.has(cacheName).then(uptodate => {
                    if (uptodate) return true
                    caches
                        .open(cacheName)
                        .then(cache => {
                            cache.addAll(myCaches[name].files)
                        })
                })
            )
            // clear old caches
        }
    })
    

Does this make sense, is it good practice? Does it make updating the cache more reliable?

like image 445
wortwart Avatar asked Mar 06 '19 16:03

wortwart


1 Answers

Most of the code examples I've seen don't add the service worker file to the cache. In my experience and from my understanding, it's not necessary for offline mode to work.

The browser will install your service worker for your PWA when you register it. The browser uses a separate facility for caching and managing service workers. It's not your responsibility to cache it.

Adding a timestamp to the filename of your service-worker is an anti-pattern. According to the article on Service Worker Lifecycle, you should avoid changing the URL of your service worker script.

What is of greater concern is the point you raised about updating the service worker, how does the browser know when to do that?

Well, according to the section Updating the service worker from the Service Worker Lifecycle article:

Most browsers, including Chrome 68 and later, default to ignoring caching headers when checking for updates of the registered service worker script. They still respect caching headers when fetching resources loaded inside a service worker via importScripts(). You can override this default behavior by setting the updateViaCache option when registering your service worker.

Your service worker is considered updated if it's byte-different to the one the browser already has. (We're extending this to include imported scripts/modules too.) The updated service worker is launched alongside the existing one, and gets its own install event.

If your new worker has a non-ok status code (for example, 404), fails to parse, throws an error during execution, or rejects during install, the new worker is thrown away, but the current one remains active.

If you've tested your PWA in offline mode, you'll notice that the browser will produce an error in the console when it tries to retrieve your sw.js file. That's nothing to be concerned about. As the last point above says, "the current one remains active".

I wonder if people are fixated on this 404 entry in the console for the service worker JavaScript when they test in offline mode and add the service worker file to the cache in a fit of yak shaving? It probably does a disservice to your site and its users by spending time and disk caching an unnecessary file in the browser.

like image 111
ashawley Avatar answered Oct 15 '22 02:10

ashawley