Developer Tools

WebAssembly (WASM) 面向 Web 开发者的实用指南

WebAssembly 实用入门——它是什么、如何工作,以及如何利用它为你的 Web 应用带来接近原生的性能表现。

10分钟阅读

Code on a screen

WebAssembly(缩写为 WASM)是过去十年中登陆浏览器最令人兴奋的技术之一。它允许你在浏览器标签页中直接运行用 C、C++、Rust 和 Go 等语言编写的代码,速度接近原生,无需任何插件。

本指南涵盖了 Web 开发者今天开始使用 WebAssembly 所需了解的一切。

什么是 WebAssembly?

WebAssembly 是一种面向基于堆栈的虚拟机的二进制指令格式。它被设计为高级语言的可移植编译目标,支持在 Web 上部署客户端和服务器应用程序。

可以把它理解为浏览器的低级汇编语言——但它是安全的、沙箱化的,并且被设计为与 JavaScript 协同运行,而非取而代之。

关键事实: WebAssembly 现已成为 W3C 标准,所有主流浏览器均支持:Chrome、Firefox、Safari 和 Edge。

为什么你应该关注?

JavaScript 功能极为强大,但也存在局限性——尤其是在 CPU 密集型任务方面,例如:

  • 视频/音频编解码
  • 图像处理和滤镜
  • 物理模拟和 3D 渲染
  • 密码学
  • 在浏览器中运行遗留的 C/C++ 代码库

WebAssembly 通过以更接近原生机器码的速度执行,填补了这些空白。

特性 JavaScript WebAssembly
执行速度 解释执行 / JIT 接近原生
类型系统 动态类型 强类型
语言支持 仅 JS C、C++、Rust、Go 等
文件格式 文本(.js 二进制(.wasm
DOM 访问 直接访问 通过 JavaScript 桥接

WebAssembly 的工作原理

典型的工作流程如下:

  1. 编写支持语言的代码(例如 Rust 或 C++)
  2. 使用工具链(例如 wasm-packEmscripten)将其编译.wasm 二进制文件
  3. 使用 WebAssembly API 在 JavaScript 中加载 .wasm 文件
  4. 直接从 JavaScript 代码中调用导出的 WASM 函数
Source Code (Rust/C++) → Compiler → .wasm binary → Browser

你的第一个 WebAssembly 模块

让我们通过一个使用 Rustwasm-pack 的简单示例来逐步了解。

第一步:安装工具链

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

# Install wasm-pack
cargo install wasm-pack

第二步:创建 Rust 库

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

#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u64 {
    match n {
        0 => 0,
        1 => 1,
        _ => {
            let mut a = 0u64;
            let mut b = 1u64;
            for _ in 2..=n {
                let c = a + b;
                a = b;
                b = c;
            }
            b
        }
    }
}

第三步:编译为 WASM

wasm-pack build --target web

这将生成一个 pkg/ 文件夹,其中包含你的 .wasm 文件和自动生成的 JavaScript 绑定。

第四步:在 JavaScript 中使用

import init, { add, fibonacci } from './pkg/my_wasm_lib.js';

async function run() {
  await init(); // Load and instantiate the WASM module

  console.log(add(3, 5));         // → 8
  console.log(fibonacci(40));     // → 102334155 (fast!)
}

run();

不使用打包工具加载 WASM

如果你没有使用打包工具,可以直接通过浏览器原生的 WebAssembly API 加载 WASM 模块:

async function loadWasm(url) {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  const { instance } = await WebAssembly.instantiate(buffer, {});
  return instance.exports;
}

const wasm = await loadWasm('/my-module.wasm');
console.log(wasm.add(10, 20)); // → 30

真实世界的使用场景

WebAssembly 已经在许多令人印象深刻的应用中大放异彩:

🎬 视频处理

FFmpeg 等工具已被编译为 WASM,使浏览器能够完全在客户端完成视频文件的裁剪、转换和编码——无需上传到服务器。

🖼️ 图像编辑

PhotopeaSquoosh 使用 WASM 直接在浏览器中运行高级编解码器(如 AVIF 和 WebP 编码器),实现快速、高质量的图像压缩。

🎮 游戏

UnityUnreal Engine 均支持将游戏导出为 WebAssembly,使完整的 3D 游戏能够在浏览器标签页中运行。

🔒 密码学

libsodium 等库编译为 WASM,让你能够完全在客户端执行快速、安全的密码学操作(哈希、加密)。

🗄️ 浏览器中的 SQLite

sql.js 等项目将 SQLite 编译为 WASM,让你拥有一个完全在本地运行的关系型数据库——无需服务器。

WASM 与 JavaScript:强强联合

一个常见的误解是 WebAssembly 是来替代 JavaScript 的。事实并非如此。它们是互补的:

  • JavaScript 负责处理 UI、DOM 操作、事件和胶水逻辑
  • WebAssembly 负责处理在 JS 中执行过慢的繁重计算

你可以像调用普通函数一样从 JavaScript 调用 WASM 函数,两者之间的桥接无缝衔接。

最佳实践:

  • 让你的 WASM 模块专注于计算——避免尝试从 WASM 操作 DOM
  • 尽量减少 JS 和 WASM 内存之间的数据复制(这是有代价的)
  • 对多线程 WASM 工作负载使用 SharedArrayBufferAtomics
  • 积极缓存你的 .wasm 文件——它们是二进制格式,压缩效果非常好

调试 WebAssembly

现代浏览器开发者工具对 WASM 提供了强大的支持:

  • Chrome DevTools 可以逐步执行 WASM 指令,甚至可以将源映射还原回原始的 Rust/C++ 代码
  • 在 JS 端使用 console.log 检查传入/传出 WASM 的值
  • wasm-bindgen CLI 包含一个 --debug 标志,可以嵌入源映射
wasm-pack build --target web --debug

未来展望:超越浏览器的 WASM

WebAssembly 不再只是浏览器技术。WASI(WebAssembly System Interface)标准将 WASM 扩展到浏览器之外——可在服务器、边缘函数和物联网设备上运行——具备可移植、沙箱化的执行模型。

WasmtimeWasmEdgeWAMR 等运行时让你可以在任何地方运行 WASM 模块,使其成为未来可移植、安全的服务器端代码的有力竞争者。

总结

WebAssembly 为 Web 开辟了全新的应用类别。以下是需要牢记的要点:

  • WASM 在所有主流浏览器中以接近原生的速度运行
  • 使用 Rust、C、C++ 或 Go 编写代码,然后编译为 .wasm
  • 使用 wasm-pack(Rust)或 Emscripten(C/C++)快速上手
  • WASM 与 JavaScript 协同工作——它们不是竞争对手
  • 真实世界的使用场景包括视频处理、图像编辑、游戏和数据库

准备好动手尝试了吗?来试试我们免费的 Base64 Encoder/Decoder——这是本站众多工具之一,采用类似 WASM 工作流的快速客户端处理技术驱动。