问题描述
我使用C ++库在加载时进行繁重的图像处理,使用emscripten进行编译并嵌入到有角度的应用程序中。
这段代码将UI冻结了几秒钟,这对用户来说永远都不好。
我想这是两个选择
- 将繁重的计算分为几个异步调用
- 使用threads (WebWorkers)
尽管我不确定每个人的可行性如何,具体取决于计算代码。
每种优点/缺点是什么?用JS / WASM处理繁重计算的通常方法是什么?
解决方法
我都做过。
仅异步仍在主线程上,因此在您遇到的情况中没有任何好处。但是,如果您可以将处理分成较小的块,并随着时间的推移将其馈送到requestIdleCallback,那么它会非常有效。缺点是您无法真正控制何时完成(如果有)。根据输出的关键程度,它可能不是最适合您的。好处是您可以访问所有API,而不仅仅是Web工作者可用的API。这是example of implementation的“拆分成较小的块,并将其提供给requestIdleCallback”,还有here's how you use it。
使用网络工作者线程具有完全释放主线程的巨大优势,这将使您更快地获得结果。缺点是您只能访问Web Worker API,必须找到一种将输出传递回主线程的方法(如有必要),并且它仍然会占用大量CPU(这意味着主线程线程在技术上是“免费的”,它可能仍会减慢速度)。如果您可以将任务分成较小的块,甚至可以生成多个线程,并获得更流畅/更快的用户体验。
主线程
- 可能会冻结页面(或者花费很长时间/永远不会结束)
- 允许您访问所有API
- 一开始比较容易,您会遇到一些比较复杂的设计
- 向/从中传递数据不会成为瓶颈
网络工作者
- 释放主线程(但可能仍会减慢整个客户端的速度)
- 并非所有API都可用
- 一旦掌握了与主线程进行通信的操作,便非常简单
- 如果您尝试产生更多并行工作的工人,则会变得复杂
- 如果您的输出不是直接构造为SharedArray的结构,则传递大量数据可能是一个问题/瓶颈