WebSockets、Web Workers、Service Workers……这些是您可能读过或听过的术语。也许不是全部,但至少有一个。即使您对前端开发非常熟悉,您也可能需要查看它们的意思。或者,也许您像我一样,偶尔会把它们搞混。这些术语听起来和看起来都非常相似,很容易混淆。
所以,让我们一起把它们分解并区分 WebSockets、Web Workers 和 Service Workers。不是深入研究并亲身体验每个细节,更像是一个小帮手,方便您下次我需要复习时可以收藏起来。
快速参考
我们将从高级概述开始,快速比较和对比。
功能 | 它是什么 |
---|---|
WebSocket | 在浏览器和服务器之间建立一个开放且持久性的双向连接,以便通过事件触发的单个连接发送和接收消息。 |
Web Worker | 允许脚本在后台的单独线程中运行,以防止脚本在主线程上相互阻塞。 |
Service Worker | 一种类型的 Web Worker,它创建一个后台服务,充当浏览器和服务器之间网络请求的中间件,即使在离线情况下也能正常工作。 |
WebSockets
WebSocket 是一种双向通信协议。可以把它想象成您和朋友之间持续的通话,除非一方决定挂断,否则通话不会结束。唯一的区别是您是浏览器,您的朋友是服务器。客户端向服务器发送请求,服务器通过处理客户端的请求进行响应,反之亦然。

通信基于事件。建立一个 WebSocket
对象并连接到服务器,服务器之间的消息会触发发送和接收它们的事件。
这意味着当建立初始连接时,我们会进行客户端-服务器通信,其中建立连接并保持活动状态,直到客户端或服务器选择通过发送 CloseEvent
来终止连接。这使得 WebSockets 成为需要在客户端和服务器之间进行持续且直接通信的应用程序的理想选择。我见过的定义大多都将聊天应用程序列为常见用例——您输入一条消息,将其发送到服务器,触发事件,服务器会以数据进行响应,而无需一遍又一遍地 ping 服务器。
**考虑以下场景**:您出门在外,决定打开 Google 地图。您可能已经知道 Google 地图的工作原理,但如果您不知道,它会在您连接到应用程序后自动找到您的位置,并跟踪您去过的任何地方。它使用实时数据传输来跟踪您的位置,只要连接保持活动状态。这就是 WebSocket 在浏览器和服务器之间建立持久的双向对话以使数据保持更新的方式。使用实时比分的体育应用程序也可以通过这种方式使用 WebSockets。
WebSockets 与 Web Workers(以及我们将要看到的 Service Workers)之间最大的区别在于它们可以直接访问 DOM。而 Web Workers(和 Service Workers)在单独的线程上运行,WebSockets 是主线程的一部分,这使得它们能够操纵 DOM。
有一些工具和服务可以帮助建立和维护 WebSocket 连接,包括:SocketCluster、AsyncAPI、cowboy、WebSocket King、Channels 和 Gorilla WebSocket。MDN 有一个 包含其他服务的运行列表。
更多关于 WebSockets 的信息
- 介绍 WebSockets – 将套接字带到 Web (web.dev)
- 思考网站的功耗 (Chris Coyier)
- WebSocket API (MDN 文档)
- 最新的浏览器支持 (Caniuse)
Web Workers
考虑以下场景:您需要执行大量复杂的计算,同时还要更改 DOM。JavaScript 是一种单线程应用程序,运行多个脚本可能会破坏您尝试更改的用户界面以及正在执行的复杂计算。
这就是 Web Workers 发挥作用的地方。
Web Workers 允许脚本在后台的单独线程中运行,以防止脚本在主线程上相互阻塞。这使得它们非常适合增强需要密集操作的应用程序的性能,因为这些操作可以在后台的单独线程上执行,而不会影响用户界面渲染。但它们并不擅长访问 DOM,因为与 WebSockets 不同,Web Worker 在其自己的线程中,而不是在主线程之外运行。
Web Worker 是一个对象,它通过使用 Worker
对象执行脚本文件来执行任务。当我们谈论 worker 时,它们往往属于以下三种类型之一。
- **专用 Worker:**专用 worker 只能被调用它的脚本访问。它仍然执行典型 Web Worker 的任务,例如它的多线程脚本。
- **共享 Worker:**共享 worker 与专用 worker 相反。它可以被多个脚本访问,并且实际上可以执行 Web Worker 执行的任何任务,只要它们与 worker 位于同一个域中。
- **Service Worker:**Service Worker 充当应用程序、浏览器和服务器之间的网络代理,允许脚本即使在网络脱机的情况下也能运行。我们将在下一节中介绍这一点。
更多关于 Web Workers 的信息
- “远离主线程” (Chris Coyier)
- 2021 年 Web Workers 的现状 (Chris Coyier)
- Web Workers 简介 (Zapier)
- Web Workers API (MDN 文档)
- 最新的浏览器支持 (Caniuse)
Service Workers
有一些事情是作为开发人员我们无法控制的,其中之一是用户网络连接。用户连接到的任何网络都是它本身。我们只能尽力优化我们的应用程序,使其在任何使用的连接上都能获得最佳性能。
Service Workers 是我们可以做的事情之一,可以逐步增强应用程序的性能。Service Worker 位于应用程序、浏览器和服务器之间,提供一个安全的连接,它在后台的单独线程中运行,这要归功于——您猜对了——Web Workers。正如我们在上一节中学到的,Service Workers 是三种类型的 Web Workers 之一。
那么,为什么您需要一个 Service Worker 位于您的应用程序和用户的浏览器之间呢?再说一次,我们无法控制用户的网络连接。假设连接由于某种未知原因而断开。这将中断浏览器和服务器之间的通信,阻止数据来回传递。Service Worker 保持连接,充当异步代理,能够拦截请求并执行任务——即使在网络连接断开后也能正常工作。

这通常被称为“离线优先”开发的主要驱动因素。我们可以将资产存储在本地缓存中,而不是网络中,在用户离线时提供关键信息,预取内容以便在用户需要时准备好,并提供对网络错误的回退。它们完全异步,但与 Web 套接字不同,它们无法访问 DOM,因为它们在自己的线程上运行。
关于 Service Worker 的另一个重要事项是它们会拦截应用程序的每个请求和响应。因此,它们具有一些安全隐患,最值得注意的是它们遵循同源策略。因此,这意味着不能从 CDN 或第三方服务运行 service worker。它们还需要安全的 HTTPS 连接,这意味着您需要 SSL 证书才能运行它们。
更多 Service Worker 信息
- 将 Service Worker 添加到您的网站(Chris Ferdinadi)
- Service worker 概述(Chrome 开发人员)
- 使用 Service Worker 减小 HTML 负载(Philip Walton)
- Service Worker 食谱(Mozilla)
- Service Worker API(MDN 文档)
- 最新浏览器支持(Caniuse)
总结
这是一个关于 Web 套接字、Web 工作者和 Service Worker 之间差异(和相似之处)的超高级别解释。再次强调,术语和概念足够相似,以至于容易混淆,但希望这能让你更好地了解如何区分它们。
我们从一个快速参考表开始。以下是相同的内容,但略微扩展以进行更深入的比较。
功能 | 它是什么 | 多线程? | HTTPS? | DOM 访问? |
---|---|---|---|---|
WebSocket | 在浏览器和服务器之间建立一个开放且持久性的双向连接,以便通过事件触发的单个连接发送和接收消息。 | 在主线程上运行 | 不需要 | 是 |
Web Worker | 允许脚本在后台的单独线程中运行,以防止脚本在主线程上相互阻塞。 | 在单独的线程上运行 | 需要 | 否 |
Service Worker | 一种类型的 Web Worker,它创建一个后台服务,充当浏览器和服务器之间网络请求的中间件,即使在离线情况下也能正常工作。 | 在单独的线程上运行 | 需要 | 否 |
很棒的文章 Aisha,这很有启发性
感谢更新
Service Worker 和其他工作者的一个关键架构区别在于,网页/选项卡控制常规工作者的生命周期和激活,而 Service Worker 由浏览器启动/停止,并且仅在事件处理程序持续时间内保证存活。
Shared Worker 与 Service Worker 最相似,因为它在来自同一来源的选项卡之间共享。但 Shared Worker 的生命周期由应用程序控制 - 因此您可以根据需要保持它,并且它可以是状态化的。Service Worker 的生命周期由浏览器控制,并且经常在闲置时被终止。Service Worker 可以每秒启动/停止多次(只要没有事件处理程序正在运行)。
不幸的是,Shared Worker 尚未在 Chrome Android 上实现,但已在所有其他主要浏览器上实现。
此问题跟踪 Chrome Android 上的 Shared Worker - 希望很快推出!并且还有一些关于 Service Worker 和 Shared Worker 之间权衡的讨论。