【问题标题】:Difference between clientsClaim and skipWaitingclientsClaim 和 skipWaiting 的区别
【发布时间】:2019-09-20 11:17:52
【问题描述】:

我试图了解skipWaitingclientsClaim 之间的区别。在我的理解中:调用skipWaiting 将导致新的服务工作者跳过等待阶段,并立即变得活跃。然后clientsClaim 也可以“声明”任何其他打开的标签。

我从在线文档中收集到的内容:

  • skipWaiting 跳过等待阶段,立即变为活动状态source

  • clientsClaim立即开始控制页面source

在我在网上找到的每个帖子中,我通常总是看到clientsClaimskipWaiting 一起使用。

但是,我最近发现了一个只使用clientsClaim 的服务人员,我很难理解clientsClaimskipWaiting 之间的实际区别是什么,在什么情况下你会使用clientsClaim不是 skipWaiting?

我对此的想法,这可能是我错的地方,但这是我对它的理解: 打电话clientsClaim,而不是skipWaiting 是多余的吗?考虑:

  • 当所有打开的页面都关闭时,新的 Service Worker 将变为活动状态(因为我们没有使用 skipWaiting
  • 当我们的新服务工作者被激活时,我们调用clientsClaim,即使我们只是关闭了所有打开的页面来激活新的服务工作者。应该没有其他页面可以控制,因为我们刚刚关闭了它们。

谁能帮我理解一下?

阅读skipWaiting上的文档

阅读clientsClaim上的文档

阅读 Jake Archibald 的 service worker lifecycle,并玩弄 this demo

阅读一堆 stackoverflow 帖子、离线食谱、不同的博客文章等。

【问题讨论】:

    标签: service-worker progressive-web-apps


    【解决方案1】:

    self.skipWaiting() 完全符合您的描述:

    强制等待的 Service Worker 成为活动服务

    在这个意义上,“活动”并不意味着任何当前加载的客户端现在正在与该服务交谈。相反,它意味着服务现在是新客户端请求时要使用的服务。

    这就是Clients.claim() 的用武之地:

    最初注册 Service Worker 时,页面在下次加载之前不会使用它。

    如果不调用claim,任何现有客户端仍将继续与旧服务工作者通信,直到加载完整页面。

    虽然大多数时候将skipWaitingClients.claim 结合使用是有意义的,但情况并非总是如此。如果由于 Service Worker 不向后兼容而导致用户体验不佳,则不应调用 Clients.claim。相反,下次刷新或加载客户端时,它现在将拥有新的服务工作者,而无需担心重大更改。

    【讨论】:

    • 谢谢!这已经说明了很多。所以只要确保我正确理解这一点,假设我在标签中打开了我的网站:tab-a。如果我调用skipWaiting,并刷新tab-a,新的Service Worker 将激活,但tab-a 实际上仍在使用 Service Worker? (例如:在开发工具中,您会看到 service worker #3071 处于活动状态并正在运行,但 previous service workerservice worker #3070 我实际上仍在控制页面?此外,仅使用clientsClaim,但 skipWaiting?
    • 你描述的情况是正确的。 IIRC 您实际上会看到两者都处于活动预刷新状态。关于clientsClaim单独使用的用例,我想不出一个。
    【解决方案2】:

    Service Worker 中skipWaiting() 和Clients.claim() 的区别

    要理解的一个重要概念是,要使服务工作者在页面上运行,它必须是页面的控制器。 (您实际上可以在Navigator.serviceWorker.controller 中看到此属性。)要成为控制器,必须首先激活服务工作者,但这本身还不够。只有通过 service worker 请求的页面才能被控制。

    通常情况下是这样,尤其是当您只是更新服务工作者时。另一方面,如果您是第一次在页面上注册 Service Worker,那么 Service Worker 将被安装并激活,但它不会成为页面的控制器,因为该页面不是通过服务请求的工人。

    您可以通过在激活处理程序中的某处调用Clients.claim() 来解决此问题。这只是意味着您无需刷新页面即可看到 service worker 的效果。

    关于这实际上有多有用存在一些问题。该规范的作者之一 Jake Archibald 有 this 对此发表评论:

    我看到很多人将 clients.claim() 作为样板,但我自己很少这样做。它只在第一次加载时才真正重要,并且由于渐进式增强,页面通常在没有 service worker 的情况下正常工作。

    关于它与其他选项卡的使用,如果这些选项卡不是通过服务人员请求的,它只会再次生效。可能会出现这样一种场景,即用户在不同的选项卡中打开了相同的页面,并且这些选项卡打开了很长时间,在此期间开发人员引入了 service worker。如果用户刷新了一个选项卡而不刷新另一个选项卡,则一个选项卡将有服务工作者,而另一个则没有。但这种情况似乎有些不常见。

    skipWaiting()

    Service Worker 在安装后被激活,如果当前没有其他 Service Worker 正在控制范围内的页面。换句话说,如果您为由旧服务人员控制的页面打开了任意数量的选项卡,那么新服务人员将不会激活。因此,您可以通过关闭所有打开的选项卡来激活新的 service worker。在此之后,旧的 service worker 控制零页,因此新的 service worker 可以变得活跃。

    如果你不想等待老的 service worker 被杀死,你可以打电话给skipWaiting()。通常,这是在install 事件处理程序中完成的。即使旧的 Service Worker 正在控制页面,它也会被杀死,这样就可以激活新的 Service Worker。

    【讨论】:

    • 如果 PWA 由 Service Worker 提供服务,并且 PWA 在 Service Worker 范围内创建了一个带有 src 的 iframe,那么 Service Worker 是否也提供 iframe 内容? iframe 文档是否必须执行任何特殊操作才能获得其父级的 service worker 的服务?
    猜你喜欢
    • 1970-01-01
    • 2013-08-07
    • 2011-10-20
    • 2020-01-23
    • 1970-01-01
    • 2014-10-09
    • 2010-12-21
    • 2011-05-11
    • 2014-01-24
    相关资源
    最近更新 更多