Service Worker文件需要缓存吗?
上篇译文 Service Worker缓存和HTTP缓存 提到:在请求service-worker.js文件时不需要添加时间戳去考虑其本身的缓存。
我在使用上篇文章中提到的
offline-plugin
插件优化(改造)公司官网项目(多页面多入口的纯静态页面,应该适合缓存下)时,因为必须要在入口页面添加,我们只能从html文件直接引入 ,具体参考 offline-plugin for webpack ,构建好项目进行测试的时候,控制台一直报错Uncaught ReferenceError: ExtendableEvent is not defined
,网上查找答案 Uncaught ReferenceError: ExtendableEvent is not defined 后发现:
回答一跟我的情况一样,我们在html文件中直接引入 offline-plugin
插件生成 sw.js,导致 offline-plugin
的依赖并没有正确引入,也就是说我们只能在 main.js入口文件中 引入 offline-plugin
runtime配置,不然会报错的(这种情况我之前试过也不行,因为我用的 html-webpack-plugin
插件的问题,导致在引入sw.js时候路径跟 service worker作用域 scope 不一致,导致service worker安装失败)。
回答二,提到了 使用 workbox-webpack-plugin
插件来替换。我才采用新插件对官网使用后,在构建后使用完美。
我们在html注册servcie worker
// index.html(主页)
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
我们可以看到,引入的时候没有对 service-worker.js 加以版本控制(之前我是在后缀加入时间戳)。我就在想了啊,workbox这可以google主动封装亲手搞的东西,按照我们以往长尝试:如果我们构建新版后,service-worker.js 文件没有更新,浏览器又默认开启HTTP缓存,那岂不我们在service-worker.js中定义的新文件缓存列表则不会剩下。google会犯这么低级的错误吗?当然不会了,google还是google,毕竟大厂,怎么可能连这点都想不到呢。
以下答案来源于: https://stackoverflow.com/questions/55027512/should-i-cache-the-serviceworker-file-in-a-pwa :
我见过的大多数代码示例都没有将service worker文件加入缓存。根据我的经验和我的理解,离线模式下这并不是必须的。
在你pwa应用中注册service worker时浏览器将安装它。浏览器使用了单独的设施来缓存和管理service worker文件。缓存或者不缓存并不是你的责任。
在servcie worker文件后边添加一个时间戳是一个反模式。根据文章 Service Worker 生命周期,你应该避免在service worker脚本后改变请求url(添加时间戳)。
更令人关注的是你提出的关于service worker文件的更新,浏览器是如何知道在何时执行此操作?
我们根据上篇文章,提到的 更新service worker 小结:
大部分浏览器,包括Chrome 69和最新版,在检查servcie worker文件更新时会忽略缓存头。但是如果你在servcie worker文件中 使用
imortScripts()
方法时,仍会检查缓存头。你可以在注册servcie worker时通过设置updateViaCache
选项覆盖这个默认行为.
如果service worker文件和旧的文件(如果已经存在)存在字节不同(内容不同)的情况下会考虑更新(我们在扩展此内容,包括其中导入的模块/脚本)。更新的servcie worker和现有的并存并启动,并执行对应install事件。
如果你的网络有一个非正确的状态码(比如说 404),解析失败,然后在执行的抛出一个错误,或者在install时reject,新的servcie woker则被扔掉,当前的service worker仍然活跃。
如果你在离线模式下测试pwa应用,你会注意到浏览器在尝试检索sw.js文件时在控制台打印一个错误。那也不用担心,如上最后一点提到的,当前的service worker仍然可用。
我想知道,当用户在脱机模式下测试pwa并将servcie worker文件缓存起来,试图去修复404的问题,这可能会花费时间和磁盘在浏览器中缓存不必要的文件,从而对您的网站及其用户造成损失?如同文章中提到的:
通过以上分析我们发现,service worker文件本身没必要考虑缓存,反而在servcie worker文件中通过 importScripts()
引入的脚本需要考虑缓存(也就是下图中的 workbox-08e0b74e.js 文件),我查看 workbox-webpack-plugin
插件生成servcie-worker.js文件:
我们查看构建好的目录:
这么一番折腾下来,情况就显而易见了。我们起初怀疑 workbox 没有考虑到缓存(从常识来说,疑问出发点是没问题的),但是结果是浏览器本身人家专门对servcie worker文件做了处理。。。
参考资料: