Why My Content Served by PWA Service Worker Not Updating?

      ☕ 4 min read

Have you been in following situations?

Your PWA website console log keeps saying:

New content is available; please refresh.

But refreshing just does not seem to work - old content and the log both stick.

Quick Solution

For you who are in a hurry and cares just the solution, close and start your whole web browser, not just tabs, and content should be updated normally.

Why does this happen?

You are using service worker to make your website a PWA(Progressive Web App). The new content of your website is going to be served by a new-version service worker, but it is waiting to replace the old version. The way how your web browser maintains service worker lifecycle apparently gets in the way, however, it actually does you good.

Service Worker Lifecycle

Jake Archibald has written an excellent dive-in on service worker, and I think it definitely worth a read. To sum up briefly, a service worker lifecycle consists of following state:

stateDiagram
[*] --> installing: js on page calls navigator.serviceWorker.register()
note right of installing
  new service worker
  gets "install" event
end note
installed: installed/waiting
installing --> installed: installEvent.waitUntil() got resolved promise
installed --> activating: wait until earlier service worker controls zero client
note right of activating
  new service worker
  gets "activate" event
end note
activating --> activated: activateEvent.waitUntil() got resolved promise
note right of activated
  new service worker 
  has fully come to power
end note
activated --> redundant: when replaced by a newer version
redundant --> [*]
  • installing: navigator.serviceWorker.register() is called, the script is downloaded and parsed, and service worker gets install event, where it will use a promise in installEvent.waitUntil() to signal whether the install process succeed or not;
  • installed/waiting: installEvent.waitUntil() got a resolved promise. If there has already been a service worker of a earlier version, web browser will keep our newcomer wait until the earlier one controlling zero client(a client here refers to mostly web pages in the service worker’s scope). Here is where your update blocks.
  • activating: service worker got activate event, which means the old service worker has gone, if there was one. It’s time for our newcomer to do housekeeping stuff like flushing old cache and claiming existing pages. A promise in activateEvent.waitUntil() is used to signal when things are done.
  • activated: The service worker has fully come to power, and it will got events like fetch and push from claimed pages.
  • redundant: Discarded, Either failed install, or it’s been replaced by a newer version.

Why Update Blocks

service worker info in developer panel
service worker info in developer panel

Web browsers keep new service worker waiting to avoid possible behavior conflict and incompatibility among two service workers of different version, and pages in their scope.

If browsers let our new service worker skip waiting, kick out and replace the outdated one immediately by default, already-opened tabs whose content and scripts are originally served by outdated service worker, may not work well with the new service worker, since their cache logic and program logic are designed to cooperate with the outdated service worker.

Thus, the browser choose a way with less surprises(shock).

Why normal refresh(F5) not working?

Look at address bar. The address does not change before and after normal refresh, therefore, the tab remains to be a client of the outdated service worker.

If your visitor has only one tab of your website in his/her browser, then the outdated service worker will give its control right to the new one when the user navigate the tab to other website(zero client left).

Takeaway

If you are worrying about using a PWA library may keep users from getting updates, all you need to do is to keep calm and cool. New contents will get available when your visitors close and start their browsers again.

However, If the waiting is really drive you anxious, you may consider display a new-version-available message to your visitors, though keep in mind skipWaiting may bring surprises discussed above.

Besides, force-reload(shift-reload, aka, shift + F5) bypasses service worker entirely, the page loaded is not controlled by service worker in any way. This feature is in the service worker spec.

Share on

nanmu42
WRITTEN BY
nanmu42
To build beautiful things beautifully.

What's on this Page