Angular:先安装Service Worker,然后再进行其他操作

时间:2019-11-19 18:29:57

标签: angular service-worker progressive-web-apps

我正在用Angular编写PWA,它需要准备好从单个页面加载脱机。服务工作者生命周期的文档指定该工作者已安装但未立即激活:https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle

这是设计使然,可以通过致电clients.claim()来否决。

问题在于,在整个应用程序加载完成后 后,Angular会加载服务工作者,因此claim()没什么可声明的。这意味着必须重新加载页面,然后将所有调用都缓存(在我的情况下有效),但这似乎是糟糕的用户体验。

我看到并尝试了以下解决方案,但都陷入了困境:

  • app.component.ts中收听服务工作者上的install事件,以便我可以等待进行需要缓存的调用,直到调用claim()之后。 SwUpdate对此事件一无所知(仅更新),虽然可以选择以下选项,但这是没有意义的,因为尚未加载服务工作者,因此navigator.serviceworker为null: navigator.serviceWorker.controller.addEventListener('statechange', (stateChangeEvent: Event) => {})
  • 将此添加到服务人员: self.addEventListener('install', (event) => {}) 但是在测试时,我需要勾选“重新加载时更新”,因此每个页面加载都将有一个安装事件,这意味着我需要某种方式使其仅发生一次,以防止陷入无限的重新加载循环。我尝试使用localstorage进行此操作,但服务人员无法访问该存储。显然,它可以访问IndexedDB,但是我仍然需要学习它的工作方式,整个“首次加载页面”策略并不适合我
  • 确保Angular会先加载Service Worker js。当然,安装是异步的,因此这意味着我的应用程序存在竞争状况。我还没找到如何影响这个加载顺序的方法。我尝试将ServiceWorkerModule.register('/custom-sw.js')首先放在app.module.ts中,但这没什么区别。

1 个答案:

答案 0 :(得分:0)

我相信您可能会错过对skipWaiting()link)的呼叫。

skipWaiting()install事件中调用时,将立即移至activate事件,而无需用户重新加载页面。

clients.claim()事件中的

activate将声明当时有任何可用的客户端。

如果您不调用skipWaiting(),则在下一次重新加载页面之前不会触发activate事件。