是什么

WebAssembly(简称 WASM):一种二进制指令格式,用于在 Web 上以接近原生的速度运行代码。

关键点:

一、它不是一种编程语言

WASM 是编译目标——你用 C/C++/Rust/Go 等语言写代码,编译成 .wasm 文件,在浏览器中运行。

二、它不是 JavaScript 的替代品

WASM 被设计为与 JavaScript 协同工作:

  • JS 负责 DOM 操作、业务逻辑、胶水代码;
  • WASM 负责计算密集的部分。

三、它是 W3C 标准

由所有主流浏览器支持(Chrome、Firefox、Safari、Edge)。

为什么需要它

JavaScript 是解释执行(后经 JIT 编译优化)的动态语言。在大多数场景下够快,但有天花板:

  • 动态类型带来的运行时开销;
  • 垃圾回收的不确定性;
  • 对某些计算模式(如密集的数值计算)不够高效。

WASM 的设计目标:

  • 可移植:编译一次,到处运行;
  • 高效:体积小、加载快、执行接近原生;
  • 安全:运行在沙箱中,遵循浏览器的同源策略等安全模型;
  • 与 Web 互操作:能调用 JS,也能被 JS 调用。

与 asm.js 的关系

历史:在 WASM 之前,Mozilla 推出了 asm.js ——JavaScript 的一个"严格子集",能被浏览器高度优化(类型确定,没有动态特性)。

问题:它仍然是文本格式,解析慢,体积大。

WASM 的改进:二进制格式——解析快得多,体积小得多。

WASM 可以看作是 asm.js 思想的正式化和升级。

工作原理

一、编译

C/C++ 源码 → (Emscripten / Clang) → .wasm 模块
Rust 源码  → (wasm-pack / cargo)  → .wasm 模块

二、加载与实例化

const { instance } = await WebAssembly.instantiateStreaming(
  fetch('module.wasm'),
  imports   // 提供给 WASM 的 JS 函数
);
instance.exports.myFunction();

三、执行

WASM 运行在一个栈式虚拟机上(一种抽象的指令集),由浏览器编译成本地机器码执行。

关键特性

一、线性内存

WASM 有一块连续的、可增长的线性内存(ArrayBuffer)。

  • JS 和 WASM 可以共享这块内存;
  • 这避免了昂贵的数据拷贝;
  • 但 WASM 不能直接访问 JS 的对象或 DOM——必须通过 JS 传值或共享内存。

这是 WASM 与 JS 交互的主要成本来源之一:数据需要序列化/反序列化,或者在共享内存中手动管理布局。

二、沙箱安全

WASM 模块:

  • 不能直接访问 DOM、文件系统、网络;
  • 只能调用宿主明确导入给它的函数;
  • 遵循浏览器的安全模型。

这种"能力式安全"模型(Capabilities-based Security)使得运行不受信任的代码成为可能。

三、确定性

WASM 的规范定义了精确的语义——在不同平台上行为一致(浮点运算等细节都有明确规定)。

应用场景

一、把已有的 C/C++ 库移植到 Web

这是最成功的应用方向。

例子:

  • FFmpeg(音视频处理)——各种在线视频编辑工具;
  • SQLite(数据库)——如基于 WASM 的本地数据库方案;
  • 图像处理库(如 ImageMagick、libvips);
  • 游戏引擎(Unity、Unreal 可以导出到 Web);
  • PDF 渲染(如 pdf.js 的部分优化);
  • 压缩/解压(zlib、brotli)。

价值:复用数十年的成熟 C/C++ 代码库,而不必用 JS 重写。

二、计算密集型任务

  • 图像/视频滤镜和处理;
  • 音频合成与分析;
  • 密码学运算;
  • 物理模拟;
  • 科学计算可视化。

三、游戏

Unity 和 Unreal 都支持导出到 WebAssembly——这让复杂的 3D 游戏可以在浏览器中运行。

四、在浏览器中运行其他语言

通过 WASM,可以在浏览器里运行 Python(如 Pyodide)、Ruby、Lua 等——这催生了在线的编程环境和科学计算 notebook(如 JupyterLite)。

五、服务端(WASI)

WASM 不只用于浏览器。

WASI(WebAssembly System Interface):为 WASM 定义了一套系统接口标准(文件、网络、时钟等),使其能在服务器和边缘设备上运行。

优势:

  • 启动极快(毫秒级,远快于容器);
  • 体积小;
  • 安全隔离(沙箱);
  • 跨平台(一次编译,到处运行)。

应用:

  • 边缘计算(如 Cloudflare Workers、Fastly Compute@Edge);
  • 插件系统(用 WASM 作为安全的插件运行时——如 Envoy 的过滤器);
  • 轻量级的服务端函数。

这使得 WASM 成为容器之外,另一种有吸引力的运行时选择(尤其对短生命周期、高并发、需要强隔离的场景)。

局限

一、DOM 访问慢

WASM 不能直接操作 DOM——必须通过 JS。

在 DOM 密集的场景中,跨边界调用的开销可能抵消掉计算性能的收益。

因此:WASM 适合"计算密集 + DOM 交互少"的任务,而非替代整个前端框架。

二、生态成熟度

工具链、调试支持、垃圾回收支持(WASM GC 规范较新)等仍在演进。

三、不是万能的加速手段

对很多 Web 应用,瓶颈是网络、渲染、DOM 操作,而非 JS 执行速度。

在这些场景中,用 WASM 不会带来明显提升。

先测量,再优化 ——这仍是首要原则。

一句话

WASM 让 Web 从"能运行代码"变成了"能高效运行任何语言编译的代码" ——它填补的是"计算密集"这一块,而非取代 JavaScript。

说明:本文为 Web 技术的知识整理。