工作箱:self.skipWaiting() 的危险

Workbox: the danger of self.skipWaiting()

我使用 Workbox 来预缓存呈现应用 shell 所需的资产,包括 index.html 的基本版本。 Workbox 假设 index.html 在缓存中可用,否则,页面导航失败,因为我在我的 Service Worker 中注册了这个:

workbox.routing.registerNavigationRoute('/index.html');

我在安装监听器中也有 self.skipWaiting() 指令:

self.addEventListener('install', e => {
  self.skipWaiting();
});

据我了解,现在有 2 install 个听众:

Workbox 的安装侦听器失败时,self.skipWaiting() 是否可以成功?这将导致出现问题状态,即资产未被预缓存但 Service Worker 被激活。这种情况是否可能发生?我应该防范吗?

我强烈推荐“The Service Worker Lifecycle”作为有关 Service Worker 安装和更新的不同阶段的权威信息来源。

总结那篇文章的一些信息,因为它适用于你的问题:

  • service worker首先进入installing阶段,无论你注册了多少install个监听器,它们都会有机会执行。正如您所建议的,Workbox 创建了自己的 install 侦听器来处理预缓存。

  • 只有当每个 install 侦听器都没有错误地完成时,service worker 才会进入下一阶段,这可能是 waiting(如果已经有一个打开的客户端使用以前版本的 service worker)或 activating(如果没有客户端使用以前版本的 service worker)。

  • skipWaiting(),如果你选择使用它,它会绕过waiting阶段,不管是否有任何开放客户端使用以前版本的服务工人.

  • 如果任何 install 侦听器失败,调用 skipWaiting() 将不会完成任何事情,因为 service worker 永远不会离开 installing 阶段。它基本上是一个 no-op.

您应该注意的一件事是在您还使用 lazy-loading 版本化预缓存资产时使用 skipWaiting()。正如文章警告:

Caution: skipWaiting() means that your new service worker is likely controlling pages that were loaded with an older version. This means some of your page's fetches will have been handled by your old service worker, but your new service worker will be handling subsequent fetches. If this might break things, don't use skipWaiting().

因为 lazy-loading 预缓存、版本化资产在 2018 年更常见,Workbox 默认不会为您调用 skipWaiting()。 opt-in 使用它取决于你。