【发布时间】:2019-11-19 18:29:57
【问题描述】:
我正在用 Angular 编写一个 PWA,它需要准备好从单个页面加载中脱机。 Service Worker 生命周期的文档指定该 Worker 已安装但不会立即激活:https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle
这是设计使然,可以通过调用clients.claim() 来否决。
问题在于 Angular 会在 整个应用程序加载完毕后加载服务工作者,因此 claim() 没有什么可声称的了。这意味着必须重新加载页面,然后缓存所有调用(在我的情况下有效),但这似乎是一种糟糕的用户体验。
我看到并尝试了以下解决方案,但都陷入了困境:
- 在
app.component.ts中监听服务工作者的安装事件,这样我就可以等到调用claim()之后再执行需要缓存的调用。 SwUpdate 对此事件一无所知(仅更新),虽然以下可能是一个选项,但它没有意义,因为尚未加载服务工作者,因此navigator.serviceworker为空:navigator.serviceWorker.controller.addEventListener('statechange', (stateChangeEvent: Event) => {}) - 将此添加到服务人员:
self.addEventListener('install', (event) => {})但是在测试时,我需要勾选“重新加载时更新”,因此每个页面加载都会有一个安装事件,这意味着我需要有某种方法让它只发生一次,以防止陷入无限循环的重新加载。我尝试使用 localstorage 执行此操作,但服务人员无权访问它。显然它可以访问 IndexedDB,但我仍然需要了解它是如何工作的,而且整个“在首次加载时重新加载页面”策略并不适合我 - 确保 Service Worker js 先由 Angular 加载。当然,安装是异步的,所以这意味着我的应用程序会出现竞争条件。我还没有找到如何影响这个加载顺序。我尝试将
ServiceWorkerModule.register('/custom-sw.js')放在app.module.ts的首位,但这并没有什么不同。
【问题讨论】:
-
抱歉,经过进一步挖掘,我已经删除了我的答案。您使用的是最新版本的 @angular/service-worker 吗?
-
当“激活”完成时,ngsw-worker 在生成器中调用 clients.claim()
-
我使用的是最新版本,是的。我目前正在使用使用工作箱生成的服务人员。在服务人员本身中,我可以选择何时调用
claim(),所以这不是问题。问题是 Angular 使用ServiceWorkerModule.register('/custom-sw.js')安装它,但它仍然最后被加载。如果这可以先完成(在头脑中或其他地方),那可以提供更多控制。
标签: angular service-worker progressive-web-apps