如何使用WebAssembly进行繁重的计算时保持反应性UI?

问题描述

我使用C ++库在加载时进行繁重的图像处理,使用emscripten进行编译并嵌入到有角度的应用程序中。
这段代码将UI冻结了几秒钟,这对用户来说永远都不好。

我想这是两个选择

尽管我不确定每个人的可行性如何,具体取决于计算代码

每种优点/缺点是什么?用JS / WASM处理繁重计算的通常方法是什么?

解决方法

我都做过。

异步仍在主线程上,因此在您遇到的情况中没有任何好处。但是,如果您可以将处理分成较小的块,并随着时间的推移将其馈送到requestIdleCallback,那么它会非常有效。缺点是您无法真正控制何时完成(如果有)。根据输出的关键程度,它可能不是最适合您的。好处是您可以访问所有API,而不仅仅是Web工作者可用的API。这是example of implementation的“拆分成较小的块,并将其提供给requestIdleCallback”,还有here's how you use it

使用网络工作者线程具有完全释放主线程的巨大优势,这将使您更快地获得结果。缺点是您只能访问Web Worker API,必须找到一种将输出传递回主线程的方法(如有必要),并且它仍然会占用大量CPU(这意味着主线程线程在技术上是“免费的”,它可能仍会减慢速度)。如果您可以将任务分成较小的块,甚至可以生成多个线程,并获得更流畅/更快的用户体验。

主线程

  • 可能会冻结页面(或者花费很长时间/永远不会结束)
  • 允许您访问所有API
  • 一开始比较容易,您会遇到一些比较复杂的设计
  • 向/从中传递数据不会成为瓶颈

网络工作者

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