【问题标题】:Service Worker vs Shared Worker服务工作者与共享工作者
【发布时间】:2015-05-07 02:01:22
【问题描述】:

Service Worker 和 Shared Worker 有什么区别?

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

【问题讨论】:

标签: javascript html web-worker service-worker


【解决方案1】:

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

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

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

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

【讨论】:

  • Service Worker 的生命周期很短:"Developers are advised to keep in mind that service workers may be started and killed many times a second."。不过,当您说“寿命”时,您的意思可能并不相同。
  • 那么,Web Worker 只与页面一起存在,而 Service Worker 的生命周期与页面完全分离? + service worker 可以访问缓存存储和特殊事件(如“获取”)。知道他们为什么创建新实体吗?为什么不给现有的网络工作者添加一些特殊的标志,比如“页面关闭时保持活跃”之类的,并添加所需的事件和 API?
  • @NoahFreitas,这不是和共享工作者一样吗?
  • @Pacerier 这里最相关的区别是共享工作者的“寿命”是由应用程序以编程方式建立的(通过new SharedWorker 并在该工作者上调用终止);而对于服务工作者,浏览器本身会根据注册的事件侦听器决定工作者实例的生存时间和开始时间。
  • 我看到这个答案是 5 年前的。它仍然是最新的吗?
【解决方案2】:

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

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

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

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

也许他们应该调用 ServiceWorkersCloudWorkers 为了清楚起见,但并非所有服务都是云。

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

添加一些用于流式传输的 WebSockets 和用于图形的 WebGL,您可以构建一些性能类似于 multiplayer console games 的热门网络应用程序。

【讨论】:

  • 他们应该将ServiceWorkers 称为后台工作人员
  • 所有工作人员都是后台工作人员 - 这就是他们的重点,将工作推离前台 (DOM) 线程。
【解决方案3】:

2020 年 11 次更新

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

WebKit 团队明确建议在SharedWorker 看起来相关的任何地方使用ServiceWorker

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

【讨论】:

    【解决方案4】:

    加起来以前的好答案。 因为主要区别在于 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 持续时间过长,浏览器可能会决定强制关闭。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 1970-01-01
      • 2020-12-19
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 2017-07-06
      相关资源
      最近更新 更多