跳转到内容
Yuuki学习手记
GitHub

让 JavaScript 请来一位 Wasm 外援

先让 JavaScript 调用一个真正的 Wasm 加法函数,再把输入拧到整数边界,看看会发生什么。一个小模块足够让“编译后的代码怎样进浏览器”变得具体,后面再沿着 Worker、内存和模型运行时往深处走。

你熟悉的异步、TypedArray 和消息传递都会用上。这次多认识一位能一起工作的计算外援。

工具主要解决什么问题一个前端例子
JavaScript应用逻辑、事件和 Web API 组织接收文件、展示进度、更新结果
WebAssembly在宿主里执行编译后的模块,通过明确接口交互调用一段编译来的计算库
Web Worker把任务放到独立的执行线程,与页面通过消息协作长计算期间让主线程继续处理输入

Wasm 有模块、实例、导入导出以及线性内存等概念,可以与 JavaScript 共同工作。很多 C/C++ 或 Rust 计算库可以经过工具链编译到 Wasm。MDN WebAssembly 概念

运行 Wasm 的位置仍需由应用安排。 在主线程直接执行很长的计算,仍然会占用主线程;Worker 是另外一层执行与协作机制。

打开JavaScript 调用 Wasm。实验编译并实例化一个只导出整数加法的小模块:

(module
(func (export "add") (param i32 i32) (result i32)
local.get 0
local.get 1
i32.add))

对应的模块字节与 JavaScript 封装随仓库提供。先改两个输入,观察返回结果;再试 2147483647 + 1。输入前先猜一个答案,运行后再去查 i32 的范围。 这次边界碰撞,会让接口中的类型有了实感。

这个实验先让接口变得具体:JavaScript 负责调用与显示,Wasm 实例执行导出的函数。换成模型运行时后,还需要准备模型文件、张量、执行后端以及任务状态。

可以先考虑两种需求:已有成熟计算库,希望在浏览器复用;或者需要一段边界清楚、适合编译为数值计算的工作。然后测量它在整体流程中的作用。

总成本可以拆成:

下载与缓存模块 → 编译或实例化 → 准备输入 → 调用计算 → 读取输出 → 显示

对于一个很小的函数,初始化和跨边界准备可能比计算本身更值得关注。对于较大的任务,还要看内存布局、复制次数和所用算法。JavaScript 与 Wasm 的选择应放在这条完整路径里评估。

章节从前端已有经验开始连接到 AI 的问题
Worker 与内存搬运消息、ArrayBuffer、取消和过期结果怎样让推理持续工作而界面仍可操作
浏览器里的 AI 后端异步初始化、资源加载与能力检测Wasm、WebGPU 和模型运行时各在哪一层

如果想把这条线做成下一次小项目,先选择“一项固定计算,在 Worker 中调用并返回结果”,把启动、取消、错误和数据归属读清楚,再接一个实际模型。其他方向见AI 与前端的交织点。