【发布时间】:2016-10-18 06:21:29
【问题描述】:
当 Service Worker 更新时,它不会以正确的方式控制页面;它进入“等待”状态,等待被激活。
令人惊讶的是,更新后的 Service Worker 甚至在刷新页面后都无法控制选项卡。谷歌解释说:
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
即使你只打开了一个标签页,刷新页面 还不足以让新版本接管。这是由于如何 浏览器导航工作。导航时,当前页面不会 在收到响应头之前离开,即使这样 如果响应有
Content-Disposition,则当前页面可能会保留 标题。由于这种重叠,当前的服务工作者总是 在刷新期间控制客户端。要获取更新,请使用 当前的服务人员。然后,当您再次导航到演示时,您 应该看到马[更新内容]。
这种模式类似于 Chrome 的更新方式。对 Chrome 的更新 在后台下载,但在 Chrome 重新启动之前不要应用。在 同时,您可以继续使用当前版本,无需 中断。但是,这在开发过程中很痛苦,但是 DevTools 有办法让它变得更容易,我将在本文后面介绍。
这种行为在有多个标签的情况下是有意义的。我的应用程序是一个需要自动更新的包;我们不能混合和匹配旧捆绑包的一部分和新捆绑包的一部分。 (在原生应用程序中,原子性是自动的且有保证的。)
但对于单个选项卡,我将其称为应用程序的“最后打开的选项卡”,这种行为不是我想要的。我想刷新最后打开的选项卡以更新我的服务人员。
(很难想象有人真的希望在刷新最后一个打开的标签时继续运行旧的服务人员。Google 的“导航重叠”论点在我看来是一个很好的借口错误。)
我的应用程序通常只在单个选项卡中使用。在生产环境中,我希望我的用户能够通过刷新页面来使用最新的代码,但这行不通:旧的 service worker 将在刷新期间保持控制。
我不想告诉用户“要接收更新,请务必关闭或离开我的应用”。我想告诉他们,“刷新一下。”
当用户刷新页面时,如何激活我更新的 Service Worker?
编辑:我知道有一个答案是快速、简单和错误的:skipWaiting 在服务人员的安装事件中。 skipWaiting 将使新的 Service Worker 在更新下载后立即生效,同时旧页面选项卡处于打开状态。这使得更新不安全地成为非原子的;这就像在应用程序运行时替换本机应用程序包。这对我来说不行。我需要等到用户刷新最后打开的标签页。
【问题讨论】:
-
我知道有一个答案是快速、简单且不安全的:
skipWaiting在服务人员的install事件中。我不想在用户工作的过程中发现更新后就随机更换我的服务人员。我需要等到用户刷新页面。
标签: service-worker