在这里插入图片描述

JavaScript 用 30 年走完的路,WebAssembly 用 5 年就走完了。


引子:一个让 JavaScript 汗颜的数字

2017 年,Mozilla 的工程师在 Chrome DevTools 里跑了一个实验:用 C++ 写一个计算斐波那契数列的函数,分别用 JavaScript 和 WebAssembly 编译后执行。

结果:Wasm 版本比 JavaScript 快 约 20 倍

这个数字在当时的社区里炸开了锅。在此之前,"浏览器里能跑接近原生速度的代码"这件事,被认为是痴人说梦。

然后发生的事情证明,这个数字不是魔法,而是一个新时代的开始。


一、WebAssembly 是什么?

1.1 官方定义

WebAssembly(缩写 Wasm)是一种为栈式虚拟机构设计的二进制指令格式。

翻译成人话:Wasm 是一种浏览器能直接执行的机器码格式,它快得离谱,且不依赖任何特定编程语言。

它的设计目标不是取代 JavaScript,而是与 JavaScript 协同工作——JavaScript 处理 UI 逻辑和动态交互,Wasm 处理计算密集型任务。两者在同一个网页里各司其职。

1.2 它的"辈分"其实很高

WebAssembly 的历史,比大多数人以为的要长得多:

  • 2015年:Mozilla 首次提出 asm.js 的概念——一种可以被浏览器优化的 JavaScript 子集,这被认为是 Wasm 的前身
  • 2017年:Wasm 正式发布 MVP(最小可行产品)版本,Chrome、Firefox、Safari、Edge 同步支持
  • 2019年:W3C 正式成立 WebAssembly Working Group,Wasm 成为官方 Web 标准
  • 2022年:Wasm Component Model 和 WASI(WebAssembly System Interface)规范进入成熟期
  • 2024-2026年:Wasm 开始从浏览器走向服务器、边缘、物联网——它正在"脱浏览器化"

1.3 二进制意味着什么?

传统 Web 应用的工作流是:

源代码(TypeScript/JS)
    ↓ 编译
JavaScript 文本(ASCII/UTF-8)
    ↓ HTTP 传输
浏览器下载(体积大,传输慢)
    ↓ 解析
浏览器 JIT 编译(边运行边优化)
    ↓ 执行

Wasm 的工作流是:

源代码(C/C++/Rust/Go)
    ↓ 编译
Wasm 二进制(.wasm 文件)
    ↓ HTTP 传输
浏览器下载(体积小,传输快)
    ↓ 解码(极快,二进制直接解析)
    ↓ 执行

二进制格式的解码(Decoding)速度远快于 JavaScript 的解析(Parsing)+ 编译(Compilation)。以一个 10MB 的模块为例:

指标 JavaScript WebAssembly
文件体积 10 MB 约 4 MB
解析/解码耗时 约 500-2000ms 约 50-200ms
JIT 编译 需要(边跑边优化) 可选(更直接的优化路径)

二、技术原理:Wasm 是怎么跑起来的?

2.1 虚拟机的栈式设计

WebAssembly 运行在一个基于栈的虚拟机上,而不是基于寄存器的虚拟机(如 x86/ARM)。这个设计选择非常重要:

  • 栈式 VM 的指令更短:因为操作数不需要编码进指令里,指令只描述"操作",操作数从栈顶取
  • 更容易跨平台:栈的结构不依赖任何 CPU 架构,一条 Wasm 指令在 x86 和 ARM 上行为完全一致
  • 更容易验证安全性:在执行前就可以完整验证所有操作,不会出现越界内存访问

一条简单的加法指令在 Wasm 中看起来是这样的(文本格式,.wat):

;; 加法: 从栈顶取两个值,相加,结果压回栈顶
(i32.add (i32.const 3) (i32.const 5))
;; 结果: 栈顶值为 8

编译器负责把高级语言翻译成这种栈式指令,虚拟机负责执行它。

2.2 内存模型:线性内存

Wasm 运行时有一块线性内存(Linear Memory),是一个可增长的字节数组(ArrayBuffer)。

// JavaScript 端可以操作 Wasm 内存
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100 })
// initial: 初始 10 页(每页 64KB),即 640KB
// maximum: 最大 100 页,即 6.4MB

Wasm 代码在这块内存里读写数据,JavaScript 可以同步读写同一块内存——这是两者互相操作数据的主要方式。

2.3 与 JavaScript 的互操作

Wasm 和 JavaScript 的关系不是"取代",而是"协作":

// 1. 加载 Wasm 模块
const response = await fetch('compute.wasm')
const buffer = await response.arrayBuffer()
const { instance } = await WebAssembly.instantiate(buffer)

// 2. 调用 Wasm 函数
const result = instance.exports.compute_square(7)  // 返回 49

// 3. Wasm 函数可以反过来调用 JavaScript 函数
// 通过 import 机制,Wasm 拿到 JavaScript 的函数引用后即可调用

这段互操作代码只有几行,但背后的设计非常精妙:Wasm 可以导入(import)任何 JavaScript 函数作为自己的外部依赖,而 JavaScript 也可以拿到 Wasm 导出的(export)函数直接调用。


三、性能真相:Wasm 到底有多快?

3.1 benchmark 实测数据

以下数据来自多个社区 benchmark 和 Mozilla/WASM 官方测试的综合结果(不同场景数据差异较大,仅供参考):

场景 JavaScript 基准 WebAssembly 提速倍数
斐波那契数列(递归) 基准 ~18x faster 18x
SHA-256 加密哈希 基准 ~10x faster 10x
图像处理(滤镜/卷积) 基准 ~8-15x faster 12x
PDF 渲染(poppler/wasm) 基准 ~5x faster 5x
物理模拟(Box2D) 基准 ~8x faster 8x
JSON 序列化(simdjson) 基准 ~3-5x faster 4x
矩阵乘法 基准 ~20x faster 20x

3.2 性能来源的三层解剖

第一层:编译时优化

JavaScript 是动态类型语言,JIT(Just-In-Time)编译器在运行时才做优化,而且需要收集足够多的运行时类型信息才能启用激进优化。Wasm 在编译阶段就完成了类型检查和优化,运行时直接执行优化后的代码。

第二层:SIMD 并行化

2022 年正式支持的 SIMD(Single Instruction Multiple Data) 是 Wasm 性能大幅提升的关键技术之一。SIMD 允许一条指令同时操作多个数据:

// 没有 SIMD:16 次运算
for (let i = 0; i < 16; i++) c[i] = a[i] * b[i]

// 有 SIMD:1 次运算(一条指令处理 16 个数据)
// SSE/AVX/NEON 级别的并行,在 Wasm 中可通过 SIMD 指令集实现

第三层:垃圾回收优化

JavaScript 的 GC(垃圾回收)是-stop-the-world 的——GC 时所有代码都要暂停。Wasm 的内存管理更精细,线性内存模型让内存分配和释放的开销极低,没有 GC 暂停带来的卡顿。

3.3 Wasm 不可能完美的地方

Wasm 有明确的边界,以下场景它帮不了你:

DOM 操作:Wasm 不能直接操作 DOM,必须通过 JavaScript 来修改页面元素。这就是为什么 Figma 的架构是"渲染引擎用 Wasm,UI 框架用 React"——Wasm 计算,JS 画图。

网络请求:Wasm 本身没有网络 API,需要通过 JavaScript 或 WASI 来发起网络请求。

启动时间:Wasm 模块的下载和实例化有固定开销,对于小规模计算任务,JavaScript 可能反而更快。


四、应用场景:谁在用 Wasm?

4.1 Figma:在线设计工具的性能天花板

Figma 是在线工具里 Wasm 用得最极致的案例。它的整个渲染引擎用 C++ 编写,编译为 Wasm,在浏览器里跑出了接近桌面应用的速度。

这意味着什么?

  • 一个需要专业设计软件的团队,不需要安装任何东西,打开浏览器就能用
  • 多人实时协作,每次操作在毫秒级同步
  • 在性能较弱的设备上,依然流畅

Figma 在 2022 年被 Adobe 以约 200 亿美元收购,Wasm 是其技术护城河的关键一环。

4.2 Google Earth:3D 渲染进入浏览器

Google Earth 的 Web 版本用 Wasm 驱动 3D 渲染引擎,突破了 JavaScript 的性能瓶颈,实现了在浏览器里流畅渲染整个地球的 3D 模型。

4.3 浏览器端 AI 推理:Qwen3-ASR-0.6B

这是 2026 年最令人震撼的 Wasm 应用之一:阿里开源的 Qwen3-ASR-0.6B 模型(语音识别),可以在浏览器里通过 Wasm 直接运行。

用户录音 → Web Audio API → Wasm 推理 → 实时文字输出
整个过程:不需要服务器,不上传数据,完全在本地完成

隐私保护 + 零服务器成本 + 毫秒级响应——这是 Wasm + 端侧 AI 的完美结合。

4.4 PDF 处理:PDF.js 的 Wasm 进化

Mozilla 的 PDF.js 是浏览器里最流行的 PDF 渲染库。2024 年后,核心渲染引擎迁移到 Wasm,PDF 解析速度提升了约 5 倍。

4.5 游戏引擎:Unity 和 Unreal 的 Web 版

Unity WebGL 导出基于 Wasm,Unreal Engine 的 Web 版本(via Emscripten)也跑在 Wasm 上。浏览器里跑 3D 游戏,在 2026 年已经不是噱头。


五、WASI:Wasm 走出浏览器的关键一跃

5.1 为什么 WASI 比 Wasm 本身更重要

WASI(WebAssembly System Interface)是一套标准化的系统 API 接口规范。有了 WASI,Wasm 模块可以像本地程序一样访问文件系统、网络、系统时钟——而这一切都是跨平台的。

没有 WASI 的 Wasm:只能在浏览器里运行,需要 JavaScript 提供所有系统能力。
有 WASI 的 Wasm:可以在任何有 WASI 运行时的平台上运行——服务器、边缘节点、物联网设备。

5.2 WASI 的设计哲学

WASI 的设计哲学是最小权限原则(Principle of Least Privilege)

每个 Wasm 模块在启动时,必须声明自己需要哪些系统能力(文件访问、网络访问、时钟等),运行时只授权被声明的部分。

// Rust + wasm32-wasi 编译时指定权限
// 假设这是一个需要文件读取能力的程序
use std::fs;

// 这个程序被限制为只能读取 /data 目录下的文件
// 即使用户恶意注入代码,Wasm 模块也无法访问其他目录

这意味着:即使 Wasm 模块被攻击,攻击者的破坏范围也被严格限制在已授权的接口内。 这是 Wasm 在服务器端安全的核心原因。

5.3 服务端 Wasm:一个新的运行时格局

2026 年,Wasm 的最重要战场已经不在浏览器里。

场景 传统方案 Wasm + WASI
插件系统 V8 沙箱 / 进程隔离 Wasm 沙箱(启动快 100 倍)
边缘计算 Docker 容器 Wasm 模块(冷启动 1ms vs 容器 100ms)
函数计算 Lambda/云函数 Wasm 边缘函数(成本更低)
数据库 UDF Lua/Python Wasm UDF(多语言统一)

Cloudflare Workers(全球最大的边缘计算平台之一)已经全面支持 Wasm;Fastly、AWS Lambda@Edge 也在跟进。


六、开发实战:如何写一个 Wasm 模块?

6.1 用 Rust 写 Wasm(推荐方式)

Rust 是目前写 Wasm 的首选语言——它的类型系统和所有权模型让内存安全代码编写变得自然,而 wasm-packwasm-bindgen 工具链让 Rust 与 JavaScript 的交互变得极其顺畅。

安装工具链:

# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 添加 wasm32 编译目标
rustup target add wasm32-unknown-unknown

# 安装 wasm-pack(构建 + 发布)
cargo install wasm-pack

编写 Rust 代码:

// src/lib.rs
use wasm_bindgen::prelude::*;

/// 计算整数平方
#[wasm_bindgen]
pub fn square(x: i32) -> i32 {
    x * x
}

/// 计算阶乘(非递归,防止栈溢出)
#[wasm_bindgen]
pub fn factorial(n: i32) -> i64 {
    let mut result: i64 = 1;
    let mut current = n;
    while current > 1 {
        result *= current;
        current -= 1;
    }
    result
}

编译为 Wasm:

wasm-pack build --target web

这会生成:

  • pkg/my_project_bg.wasm:二进制 Wasm 模块
  • pkg/my_project.js:JavaScript 胶水层代码

在网页中使用:

<script type="module">
  import init, { square, factorial } from './pkg/my_project.js'

  await init()

  console.log(square(7))        // 49
  console.log(factorial(20))   // 2432902008176640000
</script>

6.2 用 C/C++ 写 Wasm(Emscripten)

Emscripten 是最老牌的 Wasm 编译工具链,适合已有 C/C++ 代码需要迁移到 Web 的场景。

# 安装 Emscripten(需要 Docker 或 Linux/macOS)
# https://emscripten.org/docs/getting_started/downloads.html

# 编译 C 代码为 Wasm
emcc my_algorithm.c \
  -O3 \
  -s WASM=1 \
  -s EXPORTED_FUNCTIONS='["_square", "_factorial"]' \
  -o output.js

6.3 用 Go 写 Wasm(新手友好)

Go 1.21+ 内置了 Wasm 支持,门槛最低:

// main.go
package main

import (
	"fmt"
	"syscall/js"
)

func main() {
	// 注册 square 函数到 JavaScript 全局对象
	js.Global().Set("square", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
		x := args[0].Int()
		return x * x
	}))

	// 防止主 goroutine 退出
	<-make(chan bool)
}

编译:

GOOS=js GOARCH=wasm go build -o fib.wasm main.go

七、生态现状:2026 年的 Wasm 生态

7.1 工具链成熟度

工具 用途 成熟度
Rust + wasm-pack 最推荐的 Wasm 开发方式 ⭐⭐⭐⭐⭐
Emscripten (C/C++) 遗产 C/C++ 代码迁移 ⭐⭐⭐⭐
Go (GOOS=js) 快速原型 ⭐⭐⭐
AssemblyScript TypeScript → Wasm ⭐⭐⭐
Pyodide Python 科学计算 ⭐⭐⭐
wasm-bindgen Rust-JS 互操作 ⭐⭐⭐⭐⭐
Wasmtime 生产级 WASI 运行时 ⭐⭐⭐⭐
Wasmer 通用 Wasm 运行时 ⭐⭐⭐⭐

7.2 关键里程碑

  • 2022年:SIMD 支持正式稳定,Wasm 性能再上一层楼
  • 2023年:Wasm Component Model 进入草案阶段——不同语言写的 Wasm 模块可以互相调用
  • 2024年:Wasm Threads(共享内存多线程)支持主流浏览器
  • 2025年:Wasm GC(垃圾回收支持)让高级语言(Scala/Kotlin/OCaml)更容易编译为 Wasm
  • 2026年:Wasm 在边缘计算和 AI 推理领域全面落地

八、Wasm 的局限与未来

8.1 当前的主要局限

1. 工具链碎片化

不同语言到 Wasm 的编译链成熟度差异极大。Rust Wasm 生态很完善,但 Scala 或 Kotlin 还需要更多工作。Component Model 正在解决这个问题,但还需要时间。

2. 调试体验仍不理想

虽然 Chrome DevTools 已经支持 Wasm 调试(source map 支持),但体验远不如 JavaScript 调试流畅。Wasm 的二进制格式和栈式 VM 模型让断点调试比 JS 复杂得多。

3. 包体积

Rust 编译出的 Wasm 二进制,即使经过 wasm-opt 优化,也可能偏大(几十 KB 到几 MB)。这对首屏加载有影响,需要配合 HTTP/2 和压缩(brotli)使用。

4. DOM 操作的天然瓶颈

Wasm 永远需要 JavaScript 来操作 DOM,这是架构层面的限制,不是 bug。

8.2 未来趋势

趋势一:Wasm 成为"可移植性"的新标准

Docker 的创始人 Solomon Hykes 曾说:“如果 2008 年就有 Wasm + WASI,我们根本不需要创建 Docker。” 这句话正在变成现实——Wasm 的跨平台性和安全性,让它成为比容器更适合函数计算和边缘计算的运行时。

趋势二:AI 模型 Wasm 化加速

随着 llama.cpp、Qwen 等模型向 Wasm 迁移,"浏览器端运行大模型"正在从实验变成现实。这会催生一批全新的隐私优先 AI 应用。

趋势三:Component Model 统一多语言生态

Wasm Component Model 允许不同语言编译出的 Wasm 模块直接互相调用——Rust 模块可以调用 Go 模块,Go 模块可以调用 Python 模块,全部通过标准接口。2026 年这项规范正在走向成熟。

趋势四:Wasm 系统编程

WASI 0.3 规范正在让 Wasm 有能力替代轻量级系统进程,执行更复杂的系统级任务。这是 Wasm 的终极野心——成为比 Docker 更轻量、比进程更安全的通用运行时。


结语

WebAssembly 的故事,最初被定义为"让浏览器跑得快一点"的技术方案。

但它真正做到的,远不止于此。

当一个 Qwen3-ASR 模型在浏览器里安静地完成语音识别,不需要任何服务器,不需要任何数据传输——这一刻,Wasm 做的事情不是"让浏览器快一点",而是重新定义了 Web 应用能做多远

当 Cloudflare Workers 用 Wasm 模块处理全球数百万请求,冷启动时间从 100ms 降到 1ms——这一刻,Wasm 做的事情不是"优化服务器",而是重新定义了计算资源的边界在哪里

当一个用 Rust 写的 Wasm 模块在浏览器里调用了 Go 写的 Wasm 模块——这一刻,Wasm 做的事情不是"兼容多语言",而是重新定义了什么是跨平台

这就是 WebAssembly。它从浏览器出发,正在走向整个计算世界。

而这个过程,才刚刚开始。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐