在 Workbox 中使用 skipWaiting 和 clientsClaim 有什么缺点?

What are the downsides to using skipWaiting and clientsClaim with Workbox?

默认情况下 skipWaiting 在 Workbox 中设置为 false。假设您 使用 Workbox 创建的 service worker 进行缓存,将其设置为 true 有什么缺点吗?如果不这样做,您的应用程序的下一个构建将发布更新的资源 url(来自 webpack)。这些 url 将在 service worker 的预缓存清单中更新,但如果没有 skipWaiting,更新后的 service worker 将不会被激活以利用它们,直到用户关闭浏览器并重新打开。

这些更新的资源 正确加载(webpack 将使用新的哈希值加载资源),但它们永远不会被缓存,直到用户再次关闭所有打开的浏览器 运行 service worker,然后重新打开。在这种情况下,有什么理由不把 skipWaiting 设置为 true 吗?

作为一个相关问题,究竟 clientsClaim 控制什么?仅通过打开 skipWaiting 即可解决上述问题;那么 clientsClaim 是做什么的呢?

作为背景,我建议阅读“The Service Worker Lifecycle”。它是从通用服务工作者的角度编写的,但这些要点也适用于 Workbox 支持的服务工作者。

这些概念也从使用的角度create-react-app,在这个“Paying Attention while Loading Lazily”的谈话和微型网站中得到了更详细的解释。

Workbox 的实现

Workbox 使用 install 事件处理程序在预缓存清单中缓存新的或更新的条目(在需要时将 __WB_REVISION__ 查询参数附加到条目的 URL,以避免覆盖具有不同修订的现有条目),它使用 activate 事件处理程序删除以前缓存的条目,这些条目不再列在预缓存清单中。

如果skipWaiting为真,那么activate handler负责从缓存中清除过时的URLs,将在安装更新的service worker后立即执行.

Under these circumstances, is there any reason to not just set skipWaiting to true?

有一个 few risks to using skipWaiting, and to err on the side of safety, we disable it by default in Workbox. (It was enabled by default in older, sw-precache 生成的 service worker。)

让我们假设这样一种情况,在这种情况下,您的 HTML 首先加载缓存(通常是最佳实践),然后在加载后的某个时间检测到服务工作者更新。

风险 1:延迟加载指纹内容

现代网络应用程序通常结合两种技术:仅在需要时异步延迟加载资源(例如,在单页应用程序中切换到新视图)和添加指纹(哈希)以唯一标识 URLs基于它们包含的内容。

传统上,它是 HTML 本身(或包含路由信息的某些 JavaScript,这些信息也在页面生命周期的早期加载)包含对当前列表的引用 URL需要延迟加载的。

假设最初加载的网络应用程序版本(在服务工作者更新发生之前)认为需要加载 URL /view-one.abcd1234.js 才能呈现 /view-one.但与此同时,您已经部署了对代码的更新,并且 /view-one.abcd1234.js 已在您的服务器和预缓存清单中替换为 /view-one.7890abcd.js

如果 skipWaiting 为真,那么 /view-one.abcd1234.js 将作为 activate 事件的一部分从缓存中清除。作为部署的一部分,您可能已经从服务器中清除了它。因此该请求将失败。

如果 skipWaiting 为 false,那么 /view-one.abcd1234.js 将继续在您的缓存中可用,直到 service worker 的所有打开的客户端都已关闭。这通常就是您想要的。

注意:虽然使用 service worker 可以使其更有可能 运行 进入这个 class 问题,但对于所有延迟加载版本化的网络应用程序来说都是一个问题URL秒。您应该始终进行错误处理以检测延迟加载失败并尝试通过例如强制重新加载页面来恢复。如果您有适当的恢复逻辑,并且您对那个 UX 没问题,您可以选择启用 skipWaiting 无论如何。

风险 2:延迟加载不兼容的逻辑

这类似于第一个风险,但它适用于您的 URL 中没有哈希指纹的情况。如果您部署对 HTML 的更新以及对其中一个视图的相应更新,则现有客户端可以结束延迟加载 /view-one.js 的版本,该版本与 [=86] 的结构不对应=] 从缓存中获取。

如果 skipWaiting 为假,那么这不太可能发生,因为从缓存中加载的 /view-one.js 应该对应于从缓存中加载的 HTML 结构相同的缓存。这就是为什么它是一个更安全的默认值。

注意:和以前一样,这不是 service workers 独有的风险——任何动态加载未版本化 URLs 的网络应用程序可能会在最近的部署后加载不兼容的逻辑.

so what does clientsClaim do?

clientsClaim 确保范围内的所有不受控制的客户端(即页面)在服务工作者激活后立即由服务工作者控制。如果您不启用它,那么在下一次导航之前它们将不会被控制。

启用它通常比 skipWaiting 更安全,如果您希望 service worker 尽早开始填充 运行 时间缓存,这会很有帮助。

我会建议您参阅 Service Worker 生命周期文档中的 section 以获取更多信息。