首页 > 解决方案 > 如何在使用 WebAssembly 进行大量计算时保持反应式 UI?

问题描述

我使用 C++ 库在加载时进行大量图像处理,使用 emscripten 编译并嵌入到 Angular 应用程序中。
此代码将 UI 冻结几秒钟,这对用户来说从来都不是好事。

我想这里的两个选项是

虽然我不确定每个方法的可行性,但取决于计算代码。

各自的优点/缺点是什么?使用 JS/WASM 处理繁重计算的常用方法是什么?

标签: javascriptweb-workeremscripten

解决方案


我都做过。

只是异步仍然会在主线程上,所以它对你的情况没有任何好处。但是,如果您可以将处理分成更小的块并随着时间的推移将它们提供给requestIdleCallback,那么它会非常有效。这样做的缺点是您无法真正控制它何时(如果有的话)完成。根据输出的重要性,它可能不是最适合您的。好处是您可以访问所有 API,而不仅仅是 Web 工作者可用的 API。这是一个“拆分成更小的块并将其提供给 requestIdleCallback”的实现示例,下面是你如何使用它

使用web worker 线程有一个很大的好处是可以完全释放主线程,这可以让你更快地得到结果。缺点是你只能访问 web worker API,你必须找到一种方法将你的输出传回主线程(如果有必要),它仍然会占用大量 CPU(这意味着当主线程线程在技术上是“免费的”,它可能仍然会变慢)。如果您可以将任务拆分为更小的块,您甚至可以生成多个线程并获得更流畅/更快的用户体验。

主线程

  • 可能会冻结页面(或者需要很长时间/永远不会完成)
  • 让您可以访问所有 API
  • 更容易开始,有点复杂,你会进入空闲直到紧急的设计
  • 将数据传入/传出不会成为瓶颈

网络工作者

  • 释放主线程(但可能仍会减慢整个客户端的速度)
  • 并非所有 API 都可用
  • 一旦你掌握了与主线程通信的句柄,就非常简单
  • 如果你试图让更多的工人并行工作,就会变得复杂
  • 如果您的输出不能直接构造为 SharedArray,则传递大量数据可能是一个问题/瓶颈

推荐阅读