javascript - 如何在使用 WebAssembly 进行大量计算时保持反应式 UI?
问题描述
我使用 C++ 库在加载时进行大量图像处理,使用 emscripten 编译并嵌入到 Angular 应用程序中。
此代码将 UI 冻结几秒钟,这对用户来说从来都不是好事。
我想这里的两个选项是
- 将繁重的计算拆分为几个异步调用
- 使用线程(WebWorkers)
虽然我不确定每个方法的可行性,但取决于计算代码。
各自的优点/缺点是什么?使用 JS/WASM 处理繁重计算的常用方法是什么?
解决方案
我都做过。
只是异步仍然会在主线程上,所以它对你的情况没有任何好处。但是,如果您可以将处理分成更小的块并随着时间的推移将它们提供给requestIdleCallback,那么它会非常有效。这样做的缺点是您无法真正控制它何时(如果有的话)完成。根据输出的重要性,它可能不是最适合您的。好处是您可以访问所有 API,而不仅仅是 Web 工作者可用的 API。这是一个“拆分成更小的块并将其提供给 requestIdleCallback”的实现示例,下面是你如何使用它。
使用web worker 线程有一个很大的好处是可以完全释放主线程,这可以让你更快地得到结果。缺点是你只能访问 web worker API,你必须找到一种方法将你的输出传回主线程(如果有必要),它仍然会占用大量 CPU(这意味着当主线程线程在技术上是“免费的”,它可能仍然会变慢)。如果您可以将任务拆分为更小的块,您甚至可以生成多个线程并获得更流畅/更快的用户体验。
主线程
- 可能会冻结页面(或者需要很长时间/永远不会完成)
- 让您可以访问所有 API
- 更容易开始,有点复杂,你会进入空闲直到紧急的设计
- 将数据传入/传出不会成为瓶颈
网络工作者
- 释放主线程(但可能仍会减慢整个客户端的速度)
- 并非所有 API 都可用
- 一旦你掌握了与主线程通信的句柄,就非常简单
- 如果你试图让更多的工人并行工作,就会变得复杂
- 如果您的输出不能直接构造为 SharedArray,则传递大量数据可能是一个问题/瓶颈
推荐阅读
- swift - “数组索引超出范围:”从数组中获取范围时
- azure - 使用 Azure ActiveDirectory 作为 IdP 注销 Shibboleth 服务提供程序时的 opensaml::BindingException
- algorithm - 将值从一个范围重新计算到另一个范围
- jenkins - 我如何解析具有 json 的文本文件并获取数组元素
- asp.net-core-3.1 - Razor Pages 密码输入框一直显示默认点
- left-join - 对多个表进行左连接时出现雪花“爆炸连接”问题
- python - 计算python中数字的标准差
- javascript - 不知道为什么这个解决方案返回未定义(数组算法)
- javascript - 将“3+5/2”之类的字符串转换为数字
- python - VSCode for Python 中的函数参数建议/自动完成