处理 AJAX 调用的 Web 工作人员 - 优化矫枉过正

Web Workers handling AJAX calls - optimisation overkill?

本文关键字:优化 矫枉过正 工作人员 Web AJAX 调用 处理      更新时间:2023-09-26

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

最近,我

遇到了一些关于此代码的问题,我开始怀疑我是否应该花时间解决这个问题或只是转储整个解决方案。

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

  • 2 年前的 jQuery 功能建议使用 Web worker 进行 AJAX 调用
  • 这个 SO 问题似乎提出了一些不同的东西(在 Web worker 与 AJAX 调用中使用同步请求)

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

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

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


笔记:

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

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

考虑到这一点,仅将ajax调用

移出主线程不会为您带来任何好处,因为ajax调用是非阻塞的。但是,如果您必须解析 JSON 甚至更好,从大型请求中提取一小部分子集,那么 Web 工作者可以帮助您。

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

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

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

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

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

首先,您的请求已经是异步的,IO 是非阻塞的,在您的请求期间,您可以运行任何其他 Javascript 代码。在工作线程中执行回调比请求有趣得多。

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

总之,JavaScript 的异步和单线程特性非常强大,尽可能多地使用它,并且只有在你真正需要时才创建 Worker ,例如在漫长的 Javascript 过程中。

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

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

  • 分析响应以构建大型模型
  • 从响应中计算大量数据
  • 将共享 Web Worker 与模板引擎结合使用,并结合 AJAX 响应来构建 HTML,然后将返回该 HTML 以追加到 DOM。

编辑:另一个很好的阅读是:关于 Web worker 中同步请求的意见