JavaScript 被称为“单线程”。正如 Brian Barbour 所说
这意味着它只有一个调用堆栈和一个内存堆。
我们经常会遇到性能卡顿和元素或整个网站无法交互的症状。如果我们给 JavaScript 很多任务,它变得非常繁忙,那么它就不会处理其他事情,比如快速处理我们的事件处理程序。
最近在这方面出现了一个有趣的观点/反驳组合。
Das Surma 一直倡导将尽可能多的 JavaScript 从主线程转移出去。事实上,在使用 Web Workers 方面,他建议
你应该始终使用 Web Workers。
Web Workers 是在主线程之外运行 JavaScript 的主要方式。Paul Lewis 将这个问题比作 9 点钟的交通高峰
一天中最糟糕的出行时间。对于许多人来说,在其他时间出行是不可能的,因为他们需要在早上 9 点之前到达工作地点。
这正是今天很多 Web 代码的样子:所有代码都在一个线程上运行,即主线程,而且交通很拥堵。事实上,情况甚至比这更糟糕:从市中心到郊区只有一条车道,而且实际上每个人都在路上,即使他们并不需要在早上 9 点之前到办公室。
我还喜欢 Surma 将其他语言中通常称为“主线程”的“UI 线程”进行比较。如果你的工作与 UI 相关,那么就在主线程上执行;如果不是,则在主线程之外执行。他在 The Web Platform Podcast 的一期精彩节目中谈到了这一点——194: 远离主线程。我认为这将有利于改变 JavaScript 开发人员的态度和思维方式。
将某些内容从 UI 线程中移出的一个例子:状态管理。
David Gilbertson 一定读过 这篇文章,并写道
我最近看到一篇文章,认为更新 Redux 商店是 Web Workers 的一个很好的选择,因为这不是 UI 工作(非 UI 工作不应在主线程上执行)。将数据处理转移到工作线程听起来很合理,但这想法让我觉得有点,嗯,学术性。
在我看来,David 的主要观点是,我们需要做的某些繁重的 JavaScript 工作是响应用户发起的操作,而用户需要等待这些操作完成,因此在此期间 UI 无响应是可以接受的。但是对于任何非用户发起的操作——并且耗时超过 100 毫秒——他同意使用 Web Worker 是有帮助的。
(关于这个 100 毫秒的问题,值得注意的是,Surma 提出的一个主要观点是,世界上充满了低端手机——谁知道高端手机上的 100 毫秒在低端手机上会变成什么。)
在 JavaScript 中将某些内容从主线程中移出的主要技巧是使用 Web Workers。这不是黑客行为,Web Workers 实际上是将多个后台线程引入 JavaScript 的原生 API。类似于 Service Worker,它们通常位于另一个文件中
var myWorker = new Worker('worker.js');
但它们并不一定要在另一个文件中——你可以 内联它们 或者 使用库。API 并不差劲,但也并不出色。Surma 为此提供了一个库:Comlink。

Surma 在这方面的努力是长期的。它在 2018 年的 Chrome 峰会上作为一项功能出现,主题是 确保响应性的探索:在主线程上和主线程之外进行调度,并在 2019 年再次出现,主题是 主线程工作过度,报酬过低,但这次的观看次数几乎是之前的六倍(截至本次更新时)。
而且他并不孤单。Alex MacArthur 在 调整他对事件处理程序的看法,以适应在主线程之外进行操作。