47

我正在使用一个使用 Web Workers(如果可用)处理所有 AJAX 请求的代码。这些工作人员几乎只做XMLHttpRequest对象处理(没有额外的计算)。工作人员创建的所有请求都是异步的(request.open("get",url,true))。

最近,我遇到了一些关于这段代码的问题,我开始怀疑我是应该花时间修复这个问题还是直接放弃整个解决方案。

到目前为止,我的研究表明,这段代码实际上可能会损害性能。但是,我找不到任何可靠的来源支持这一点。我仅有的两个发现是:

  • 2 岁的jQuery 功能建议使用网络工作者进行 AJAX 调用
  • 这个SO question 似乎询问了一些不同的东西(在网络工作者和 AJAX 调用中使用同步请求)

有人可以指出我讨论这个问题的可靠来源吗?或者,是否有任何基准可以消除我的疑虑?

[编辑JSON.parse] 当 WebWorker 还负责解析结果 ( )时,这个问题变得更有趣了。异步解析是否提高了性能?

4

5 回答 5

29

在 jsperf 上为此创建了一个适当的基准。根据浏览器的不同,WebWorker 方法比原始 ajax 调用慢 85-95%。


笔记:

  • 由于每个请求的网络响应时间可能不同,我只测试new XMLHttpRequest()JSON.parse(jsonString);. 没有进行真正的AJAX 调用。
  • 测量WebWorker 设置和拆卸操作
  • 请注意,我正在测试单个请求,webworker 方法的结果对于多个同时请求可能会更好
  • Calvin Metcalf 向我解释说,比较 jsperf 上的同步和异步不会给出准确的结果,他创建了另一个基准来消除异步开销。结果仍然表明,WebWorker 方法明显较慢。
  • Reddit 的讨论中,我了解到在主页和 WebWorker 之间传递的数据是复制的,并且必须在此过程中进行序列化。因此,仅使用 WebWorker 进行解析没有多大意义,无论如何都必须对数据进行序列化和反序列化,然后才能在主页上使用它们。
于 2014-10-06T15:14:58.423 回答
16

首先要记住的是,网络工作者很少会因为花费更少的时间而让事情变得更快,他们让事情变得更快是因为他们将计算负载转移到后台线程,这样与用户交互相关的处理就不会被阻塞。例如,当您考虑传输数据时,进行大量计算可能需要 8 秒而不是 4 秒。但是如果在主线程上完成,整个页面将被冻结 4 秒,这可能是不可接受的。

考虑到这一点,仅将 ajax 调用移出主线程不会为您带来任何好处,因为 ajax 调用是非阻塞的。但是如果你必须解析 JSON 甚至更好,从一个大请求中提取一个小子集,那么 web worker 可以帮助你。

我听说但未确认的一个警告是,工作人员使用与主页不同的缓存,因此如果在主线程和工作人员中加载相同的资源,则可能会导致大量重复工作。

于 2014-10-07T12:10:15.860 回答
7

你在错误的地方优化你的代码。

AJAX 请求已经在单独的线程中运行,并在完成后返回主事件循环(并调用定义的回调函数)。

Web Worker 是线程的接口,用于计算昂贵的操作。就像在经典桌面应用程序中一样,当您不想通过需要很长时间的计算来阻塞界面时。

于 2014-10-07T12:55:46.850 回答
3

异步 IO 是 Javascript 的一个重要概念。

首先,您的请求已经是异步的,IO 是非阻塞的,并且在您的请求期间,您可以运行任何其他 Javascript 代码。在 worker 中执行回调比请求更有趣。

其次,Javascript引擎在同一个线程中执行所有代码,如果创建新线程,则需要处理与 worker消息api的数据通信(参见信号量)。

总之,JavaScript 的异步和单线程特性非常强大,尽可能多地使用它,并仅在您真正需要时创建工作线程,例如在较长的 Javascript 进程中。

于 2014-10-07T11:15:17.110 回答
1

根据我的经验,Web Workers应该用于 AJAX 调用。首先,它们是异步的,这意味着在您等待信息返回时代码仍会运行。

现在,使用 Worker 来处理响应绝对是您可以使用 Web Worker 的事情。一些例子:

  • 解析响应以构建大型模型
  • 从响应中计算大量数据
  • 使用带有模板引擎的 Shared Web Worker 并结合 AJAX 响应来构建 HTML,然后将其返回以附加到 DOM。

编辑:另一个不错的读物是:关于网络工作者同步请求的意见

于 2013-10-12T16:48:40.600 回答