【问题标题】:Should I cache the ServiceWorker file in a PWA?我应该在 PWA 中缓存 ServiceWorker 文件吗?
【发布时间】:2019-03-06 16:09:55
【问题描述】:

我仍然在纠结如何避免 Progressive Web Apps 中的缓存问题。任何 PWA 缓存的关键是能够更新 ServiceWorker 文件(我们称之为 sw.js)。但是细节让我有点困惑:

  • 可以在每次页面加载时执行navigator.serviceWorker.register('sw.js'),因为register() 会更新应用程序缓存,或者如果所有内容都是最新的,则什么也不做——对吗?

  • 使用navigator.serviceWorker.register('sw.js?' + Date.now()) 之类的方法来避免 HTTP 缓存是否有意义?或者,如果服务器使用 ETag,我是否安全?

  • 浏览器是否在每次页面加载时检查网络以获取更新的 sw.js?我有时在网络检查器选项卡中看不到它。

  • 如果 sw.js 在应用缓存中,浏览器是否会从那里获取它而不检查服务器是否有更新?

  • 我有时会看到像这样缓存自身的 ServiceWorker 演示脚本:

    self.addEventListener('install', ev => {
        const myCaches = {
            app: {...}, 
            sw: {
                files: [
                    '/sw.js'
                ],
                version: '1'
            }
        }
        for (let name in myCaches) {
            const cacheName = name + '-' + myCaches[name].version
            ev.waitUntil(
                caches.has(cacheName).then(uptodate => {
                    if (uptodate) return true
                    caches
                        .open(cacheName)
                        .then(cache => {
                            cache.addAll(myCaches[name].files)
                        })
                })
            )
            // clear old caches
        }
    })
    

这有意义吗,这是一种好习惯吗?它是否使更新缓存更可靠?

【问题讨论】:

  • 我不确定 ETags,但似乎浏览器将转向忽略服务工作者的 HTTP 缓存developers.google.com/web/updates/2018/06/fresher-sw
  • 这很有趣,而且似乎是个好主意。不过我不会依赖它,因为它是一个相当新的功能,而且我在规范或其他浏览器的文档中都找不到类似的东西。

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


【解决方案1】:

我见过的大多数代码示例都没有将 service worker 文件添加到缓存中。根据我的经验和理解,离线模式没有必要工作。

当您注册时,浏览器将为您的 PWA 安装您的 Service Worker。浏览器使用单独的工具来缓存和管理服务人员。缓存它不是你的责任。

在您的 service-worker 的文件名中添加时间戳是一种反模式。根据Service Worker Lifecycle的文章,你应该avoid changing the URL of your service worker script

更令人担忧的是您提出的关于更新服务工作者的观点,浏览器如何知道何时执行该操作?

好吧,根据 Service Worker Lifecycle 文章中的 Updating the service worker 部分:

大多数浏览器,包括 Chrome 68 及更高版本,默认忽略 检查注册服务的更新时缓存标头 工人脚本。他们在获取时仍然尊重缓存标头 通过importScripts() 在服务工作者中加载的资源。你可以 通过设置 updateViaCache 选项覆盖此默认行为 注册 Service Worker 时。

如果您的 service worker 与 浏览器已经拥有的那个。 (我们将其扩展到包括 也导入了脚本/模块。)更新的服务工作者启动 与现有的一起,并获得自己的install 事件。

如果您的新工作人员的状态码不正常(例如 404),则失败 解析,在执行期间抛出错误,或在安装期间拒绝, 新工人被丢弃,但当前工人仍然活跃。

如果您在离线模式下测试过您的 PWA,您会注意到浏览器在尝试检索您的 sw.js 文件时会在控制台中产生错误。这没什么好担心的。正如上面最后一点所说,“当前的仍然处于活动状态”。

我想知道当人们在离线模式下进行测试并将服务工作者文件添加到缓存中以适应牦牛剃须时,他们是否会关注控制台中服务工作者 JavaScript 的这个 404 条目?它可能会花费时间和磁盘在浏览器中缓存不必要的文件,从而对您的网站及其用户造成损害。

【讨论】:

  • 避免 404 可能确实是 app-cache sw.js 的唯一(不令人信服的)原因。虽然我还没有找到有关其他浏览器行为的文档,但不确定 HTTP 缓存。动态添加 HTTP 参数不会导致与更改文件名相同的问题。
  • 是的,服务工作者的缓存规则没有明确定义。事实上,它们在不断变化,毫不奇怪,它们在浏览器之间存在差异。这是一项新技术,因此仍在不断完善。
【解决方案2】:

我想这些事情会随着时间而发展。

我现在刚刚检查了我的实验应用。无论我是否在要缓存的 url 中包含 service-worker,pwa 总是在刷新时获取 service-worker。

事实上,这是开发者用来更新应用程序的机制。当要进行更新时,可以更新服务器上的 service-worker 版本,然后当应用程序检测到新版本的 s-w 时,它也会重新获取所有缓存的 url。根据实现的不同,重新获取可能取决于更改的校验和或每个文件与其缓存的文件的指纹。

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2023-03-03
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多