首页 > 解决方案 > 为什么 self.skipWaiting() 和 self.clients.claim() 不是服务人员的默认行为

问题描述

我正在为我的论文研究服务人员。我了解生命周期的工作原理,但我无法理解服务人员的默认更新行为。

当安装一个新的 service worker 时,当安装一个旧的 service worker 时,service worker 将不得不等待激活。使用 self.skipWaiting() 和 self.clients.claim() 可以完全激活 service worker 并控制页面。我不明白为什么这不是默认行为。我能找到的主要原因是保持代码和数据的一致性(https://redfin.engineering/service-workers-break-the-browsers-refresh-button-by-default-here-s-why-56f9417694)。有了对生命周期的一些基本了解,当服务工作者更新或我遗漏了什么时,难道不能同时保持代码和数据的一致性吗?还有其他原因吗?

这种行为在过去是否也有所不同?之后是否添加了 skipWaiting() 和 clients.claim() ?

标签: service-workerservice-worker-events

解决方案


默认设置 - 就像现在一样 - 通常更安全,并且不会强迫每个人提出各种解决方案。

  1. 用户使用 main1.js 加载页面,SWv1 注册 1 秒后,站点现在完全缓存
  2. 用户再次加载页面 - 这次是 SWv1 从缓存中加载,速度非常快。新的 SWv2 在 1 秒后注册,缓存新资产(main1.js 现在是 main2.js),通过 skipWaiting 和 clientsClaim 进行控制

现在可能发生两件事:

页面已加载 main1.js 并且浏览器已执行该脚本所说的任何内容。用户与页面等进行了交互。页面正在运行 main1.js,它希望与 SWv1 对话,但实际上控制的 SW 是 SWv2。脚本 main1.js 可能正在发送消息并尝试以只有 SWv1 理解但 v2 不知道的方式与 SW 交互。现在由于不匹配而分页。

SWv1 缓存了站点 v1 所需的所有资产。因此,如果 main1.js 在用户与页面交互时延迟加载某些内容等,浏览器将从缓存中获取。由于 SWv2 已经控制并缓存了它对资产的想法(这些现在是较新的资产),当 main1.js 尝试延迟加载最初由 SWv1 缓存的东西时,它没有找到。此外,由于这是一个新部署,资产不再位于 HTTP 服务器上。它本来在 SWv1 处理的缓存中,但 SWv2 不知道它。SWv2 知道该文件的更新版本。分页符。

重要的是要了解,并非每个站点/软件组合都是这种情况。如果您在 SW 脚本中的逻辑很少,并且 main.js 与 sw.js 的通信不太多,那么可以构建一个组合,其中 skipWaiting 和 clientsClaim 不会导致任何问题。您还可以编写这样的代码,即如果发生错误,您将向用户显示要刷新的通知。


推荐阅读