Angular: fully install service worker before anything else

点点圈 提交于 2019-12-08 03:59:40

问题


I'm writing a PWA in Angular that needs to be ready to go offline from a single page load. The documentation for the service worker life cycle specifies that the worker is installed but not active immediately: https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle

This is by design and can be overruled by calling clients.claim().

The problem with this is that Angular loads the service worker after the whole app has been loaded so claim() has nothing left to claim. That means the page has to be reloaded and then all the calls are cached (which works in my case) but that seems like a poor user experience.

I see and have tried the following solutions but have gotten stuck on all of them:

  • Listen to the install event on the service worker in app.component.ts so that I can wait to do my calls that need to be cached until after claim() has been called. SwUpdate knows nothing about this event (only updates) and while the following could be an option, it's pointless because the service worker has not been loaded so navigator.serviceworker is null: navigator.serviceWorker.controller.addEventListener('statechange', (stateChangeEvent: Event) => {})
  • Add this to the service worker: self.addEventListener('install', (event) => {}) but when testing, I need to tick "update on reload" and so each pageload is going to have an install event, meaning I need to have some way to have it happen only once ever to prevent getting in an infinite loop of reloads. I tried doing this with the localstorage but the service worker has no access to that. Apparently it has access to IndexedDB but I still need to learn how that works and this whole "reload the page on first load" strategy doesn't sit right with me
  • Ensure the service worker js is loaded by Angular before anything else. Of course, the install is async so that would mean race conditions with my app. I haven't been able to find how to influence this load order. I tried placing ServiceWorkerModule.register('/custom-sw.js') first in app.module.ts but that made no difference.

回答1:


I believe you might be missing the call to skipWaiting() (link).

skipWaiting() when called from the install event will move right on to the activate event without the user reloading the page.

clients.claim() in the activate event will claim any clients available at that time.

If you do not call skipWaiting(), the activate event is not fired until next reload of the page.



来源:https://stackoverflow.com/questions/58940683/angular-fully-install-service-worker-before-anything-else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!