38

Service Worker 和 Shared Worker 有什么区别?

我什么时候应该使用 Service Worker 而不是 Shared Worker,反之亦然?

4

4 回答 4

28

Service Worker 具有共享 Worker 之外的其他功能,并且一旦注册,它们就会在给定网页的生命周期之外持续存在。

服务工作者可以响应message事件,例如共享工作者,但他们也可以访问其他事件。处理fetch事件允许服务工作者拦截任何网络流量(源自受控页面)并采取特定操作,包括从Request/Response缓存提供响应。还计划向服务人员公开一个push事件,允许 Web 应用程序在“后台”接收推送消息。

另一个主要区别与持久性有关。一旦为特定来源和范围注册了服务工作者,它就会无限期地保持注册状态。(如果底层脚本发生变化,Service Worker 将自动更新,它可以手动或以编程方式删除,但这是例外。)因为 Service Worker 是持久的,并且其生命周期独立于 Web 浏览器中的活动页面,它为使用它们为上述推送消息提供动力之类的事情打开了大门——push只要浏览器正在运行,服务工作者就可以“唤醒”并处理事件,而不管哪些页面处于活动状态。未来的 Web 平台功能也可能会利用这种持久性。

还有其他技术差异,但从更高层次的角度来看,这些差异才是最突出的。

于 2015-03-06T22:49:57.600 回答
24

SharedWorker上下文是一个有状态的会话,旨在通过异步消息传递(客户端/服务器范式)将网页多路复用到单个应用程序中。它的生命周期是基于域的,而不是像DedicatedWorker(两层范式)那样基于单页。

ServiceWorker上下文被设计为无状态的。它实际上根本不是一个持久会话——它是控制反转(IoC) 或基于事件的持久服务范式。它服务于事件,而不是会话。

一个目的是为数据库和其他持久性服务(即云)提供用于长时间运行查询(LRQ) 的并发安全异步事件。线程池在其他语言中的作用正是如此。

例如,如果您的 Web 应用程序对各种云服务执行许多并发安全 LRQ 以填充自身,那么ServiceWorkers就是您想要的。您可以立即执行数十个安全 LRQ,而不会阻碍用户体验。SharedWorkersDedicatedWorkers不容易处理许多并发的安全 LRQ。此外,一些浏览器不支持SharedWorkers

也许他们应该改用ServiceWorkers:为清楚起见CloudWorkers,但并非所有服务都是云。

希望这个解释能引导您思考各种 Worker 类型是如何设计为协同工作的。每个都有自己的专长,但共同的目标是减少 DOM 延迟并改善基于 Web 的应用程序的用户体验。

加入一些用于流式传输的WebSockets和用于图形的WebGL ,您可以构建一些像多人控制台游戏一样运行的炙手可热的 Web 应用程序。

于 2016-11-27T01:58:33.663 回答
5

2020 11 更新

对于对此讨论感兴趣的任何人的重要细节:WebKit 不SharedWorker支持(故意删除 ~v6 或其他内容)。

WebKit 团队明确建议在ServiceWorker任何SharedWorker可能相关的地方使用。

对于希望将此功能恢复到 WebKit 的社区,请参阅这个(目前尚未解决)问题。

于 2020-11-18T06:55:07.870 回答
1

加上以前的好答案。主要区别在于ServiceWorker是无状态的(将关闭然后以明确的全局范围启动),而SharedWorker将在会话期间保持状态。

仍然有可能要求ServiceWorker在消息处理程序期间保持状态。

s.onmessage = e => e.waitUntil((async () => {
  // do things here
  // for example issue a fetch and store result in IndexedDb
  // ServiceWorker will live till that promise resolves
})())

上面的代码要求ServiceWorker在作为参数提供给waitUntil的承诺解决之前不会关闭。如果以这种方式同时处理许多消息,ServiceWorker将不会关闭,直到所有承诺都得到解决。

这可以用来无限期地延长ServiceWorker的生命,使其有效地成为SharedWorker不过,请记住,如果ServiceWorker运行时间过长,浏览器可能会决定强制关闭。

于 2021-07-21T18:45:12.090 回答