我想要达到的目标:
使用加载器/微调器渲染页面
如果
service-worker.js
已注册并处于活动状态,则检查更新- 如果没有更新,则删除加载程序
- 如果
updatefound
安装了新版本,则重新加载页面
- 否则注册
service-worker.js
- 什么时候
updatefound
,意味着安装了新的,删除加载器
- 什么时候
我正在使用sw-precache
模块来生成service-worker.js
并遵循注册码:
window.addEventListener('load', function() {
// show loader
addLoader();
navigator.serviceWorker.register('service-worker.js')
.then(function(swRegistration) {
// react to changes in `service-worker.js`
swRegistration.onupdatefound = function() {
var installingWorker = swRegistration.installing;
installingWorker.onstatechange = function() {
if(installingWorker.state === 'installed' && navigator.serviceWorker.controller){
// updated content installed
window.location.reload();
} else if (installingWorker.state === 'installed'){
// new sw registered and content cached
removeLoader();
}
};
}
if(swRegistration.active){
// here I know that `service-worker.js` was already installed
// but not sure it there are changes
// If there are no changes it is the last thing I can check
// AFAIK no events are fired afterwards
}
})
.catch(function(e) {
console.error('Error during service worker registration:', e);
});
});
阅读规范后,很明显没有类似updatenotfound
. 看起来像 通过运行get-newest-worker-algorithmserviceWorker.register
检查是否在service-worker.js
内部进行了更改,但我看不到通过公共 api 公开的类似方法。
我认为我的选择是:
- 在服务工作者注册激活后等待几秒钟,看看是否
onupdatefound
被解雇 service-worker.js
如果缓存未更新,则从代码中触发自定义事件
还有其他建议吗?
编辑:
我想出了一些代码,通过postMessage()
在 SW 注册和 SW 客户端之间使用来解决这个问题(正如@pate 建议的那样)
下面的demo尝试通过软件客户端和软件注册之间的检查来实现postMessage
,但是由于软件代码已经被缓存而失败了DEMO
编辑:
所以现在看来我无法实现我想要的,因为:
- 当服务人员处于活动状态时,您无法通过评估 SW 中的某些代码来检查更新 - 这仍然是相同的缓存 SW,没有更改
- 你需要等待
onupdatefound
,没有其他东西会通知 SW 的变化 activation
较旧的 SW 出现在之前onupdatefound
- 如果没有变化,则不会触发
activation
- SW注册
update()
不成熟,不断变化,Starting with Chrome 46, update() returns a promise that resolves with 'undefined' if the operation completed successfully or there was no update
- 设置超时以推迟视图渲染是次优的,因为对于应该设置多长时间没有明确的答案,它也取决于 SW 大小