WebAssembly 的编译和运行流程如下:
1. 源代码编写 开发者使用支持 WebAssembly 的编程语言(如 C++、Rust、Go、AssemblyScript 等)编写源代码。
2. 编译为 WebAssembly 使用编译器将源代码编译为 WebAssembly 二进制格式(.wasm 文件):
- C++:使用 Emscripten 编译器
- Rust:使用
wasm-pack或直接使用rustc的--target wasm32-unknown-unknown - Go:使用
GOOS=js GOARCH=wasm go build - AssemblyScript:使用
asc编译器
3. 加载 WebAssembly 模块 在 JavaScript 中使用 WebAssembly API 加载 .wasm 文件:
javascript// 方法1:使用 fetch 和 WebAssembly.instantiate fetch('module.wasm') .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes)) .then(results => { // 使用导出的函数 results.instance.exports.exportedFunction(); }); // 方法2:使用 WebAssembly.instantiateStreaming WebAssembly.instantiateStreaming(fetch('module.wasm')) .then(results => { results.instance.exports.exportedFunction(); });
4. 实例化 WebAssembly 模块被实例化,创建一个 WebAssembly 实例。实例化过程中:
- 分配线性内存
- 初始化全局变量
- 准备导出函数
5. 与 JavaScript 互操作
- 导入:JavaScript 可以将函数、内存等导入到 WebAssembly 模块
- 导出:WebAssembly 模块可以导出函数、内存、全局变量供 JavaScript 使用
6. 执行 通过 JavaScript 调用 WebAssembly 导出的函数,执行计算任务。
7. 内存管理
WebAssembly 使用线性内存模型,JavaScript 可以通过 WebAssembly.Memory 访问和操作 WebAssembly 的内存。
优化建议:
- 使用
WebAssembly.instantiateStreaming直接流式编译,减少内存占用 - 对于大型模块,考虑使用 WebAssembly 的流式编译特性
- 合理设计导入导出接口,减少 JavaScript 和 WebAssembly 之间的数据传输开销