服务工作者和共享工作者之间有什么区别?
我应该何时使用Service Worker而不是Shared Worker,反之亦然?
答案 0 :(得分:20)
服务工作者具有超出共享工作者可用功能的其他功能,一旦注册,它们将在给定网页的生命周期之外持续存在。
服务工作者可以响应message
事件,例如共享工作者,但他们也可以访问其他事件。处理fetch
事件允许服务工作者拦截任何网络流量(源自受控页面)并采取特定操作,包括提供来自Request
/ Response
缓存的响应。还有plans向服务工作人员公开push
事件,允许网络应用在“后台”接收推送消息。
另一个主要区别与持久性有关。一旦服务工作者注册了特定的来源和范围,它就会无限期地保持注册状态。 (如果底层脚本发生更改,服务工作者将自动更新,并且可以手动或以编程方式删除,但这是例外。)因为服务工作者是持久的,并且具有独立于Web浏览器中活动页面的生命它为诸如使用它们为上述推送消息传递提供支持之类的东西打开了大门 - 只要浏览器正在运行,服务工作者就可以“醒来”并处理push
事件,无论哪个页面处于活动状态。未来的Web平台功能也可能会利用这种持久性。
还有其他技术差异,但从更高层次来看,这些是突出的。
答案 1 :(得分:13)
SharedWorker 上下文是有状态会话,旨在通过异步消息传递(客户端/服务器范例)将网页复用到单个应用程序中。它的生命周期是基于域的,而不是基于单页的,如 DedicatedWorker (两层范例)。
ServiceWorker 上下文旨在无状态。它实际上根本不是持久会话 - 它是控制反转(IoC)或基于事件的持久性服务范例。它提供活动,而不是会议。
一个目的是为长时间运行的查询(LRQ)向数据库和其他持久性服务(即云)提供并发安全异步事件。正是线程池在其他语言中的作用。
例如,如果您的网络应用程序为各种云服务执行许多并发安全LRQ以填充自身,那么 ServiceWorkers 就是您想要的。您可以立即执行数十个安全LRQ,而不会阻止用户体验。 SharedWorkers 和 DedicatedWorkers 无法轻松处理许多并发安全LRQ。此外,某些浏览器不支持 SharedWorkers 。
为了清晰起见,也许他们应该打电话给 ServiceWorkers : CloudWorkers ,但并非所有服务都是云。
希望这种解释能让您思考各种工作者类型如何协同工作。每个都有自己的专业化,但共同的目标是减少DOM延迟并改善基于Web的应用程序的用户体验。
投放一些 WebSockets 用于流式传输, WebGL 用于显卡,您可以构建一些类似于multiplayer console games的吸烟热门网络应用。
答案 2 :(得分:0)
2020 11更新
对本讨论感兴趣的任何人的重要详细信息:{strong>不不受WebKit支持(故意删除了〜v6之类的东西)。
WebKit团队明确建议在SharedWorker
可能相关的地方使用ServiceWorker
。
对于希望将此功能恢复到WebKit的社区,请参阅this(到目前为止尚未解决)问题。
答案 3 :(得分:0)
加上之前的好答案。 主要区别在于 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 持续时间过长,浏览器可能会决定强制关闭。