Angular:先安装Service Worker,然后再进行其他操作 [英] Angular: fully install service worker before anything else

查看:102
本文介绍了Angular:先安装Service Worker,然后再进行其他操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用Angular编写PWA,它需要准备好从单个页面加载脱机.服务工作者生命周期的文档指定该工作者已安装但未立即激活:

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

这是设计使然,可以通过调用clients.claim()来否决.

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

此问题是,在整个应用程序加载完成后 后,Angular会加载服务工作者,因此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:

  • app.component.ts中收听服务工作者上的install事件,以便我可以等待进行需要缓存的调用,直到调用claim()之后. SwUpdate对此事件一无所知(仅更新),虽然可以选择以下选项,但这是没有意义的,因为尚未加载服务工作者,因此navigator.serviceworker为空: 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中,但这没什么区别.
  • 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.

推荐答案

我相信您可能会错过对skipWaiting()的致电(

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

skipWaiting()时,它将直接移至activate事件,而无需用户重新加载页面.

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

clients.claim()将声明当时有可用的客户端.

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

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

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

这篇关于Angular:先安装Service Worker,然后再进行其他操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆