WebAssembly(简称 WASM)已经成为现代计算的重要组成部分。
它让开发者能在浏览器、服务器甚至 IoT 设备中运行接近原生性能的代码。Rust 与 WASM 的结合被认为是目前最强大的组合之一:

Rust 负责编译期安全与性能,WASM 提供可移植与沙箱执行。

本文将从原理到实践,带你理解 Rust 与 WASM 的融合机制,并构建一个能在浏览器中运行的 Rust 应用。


一、什么是 WebAssembly?

WebAssembly 是一种低级字节码格式,由浏览器原生支持。它的目标是让 C/C++、Rust 等语言的程序可以编译后在 Web 环境中以接近原生的速度运行。

特点:

  • ✅ 接近原生的性能(基于线性内存模型)
  • ✅ 安全的沙箱执行(防止访问非法内存)
  • ✅ 与 JavaScript 无缝互操作
  • ✅ 跨平台(浏览器、Node.js、边缘计算环境)

在浏览器端运行 Rust 代码的典型路径是:

Rust 源码 → LLVM → WebAssembly 字节码(.wasm) → JS 调用

二、构建环境准备

1️⃣ 安装 Rust WASM 工具链

rustup target add wasm32-unknown-unknown
cargo install wasm-pack

wasm-pack 是官方推荐的打包工具,支持生成 npm 包。


三、创建项目

cargo new wasm_counter --lib
cd wasm_counter

添加依赖:

cargo add wasm-bindgen

wasm-bindgen 用于生成 JavaScript 与 WASM 之间的绑定代码。


四、编写 Rust 代码

src/lib.rs

use wasm_bindgen::prelude::*;

// 导出给 JavaScript 使用
#[wasm_bindgen]
pub struct Counter {
    value: i32,
}

#[wasm_bindgen]
impl Counter {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Counter {
        Counter { value: 0 }
    }

    pub fn increment(&mut self) {
        self.value += 1;
    }

    pub fn decrement(&mut self) {
        self.value -= 1;
    }

    pub fn value(&self) -> i32 {
        self.value
    }
}

这段代码定义了一个可供 JavaScript 调用的计数器类。
通过 #[wasm_bindgen] 宏,Rust 会自动生成 WebAssembly 接口代码。


五、构建为 WebAssembly 模块

wasm-pack build --target web

生成目录结构:

pkg/
├── wasm_counter_bg.wasm
├── wasm_counter.js
└── package.json

六、前端集成

新建一个简单的 index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Rust WASM Counter</title>
</head>
<body>
  <h1>Rust Counter</h1>
  <p id="value">0</p>
  <button id="inc">+1</button>
  <button id="dec">-1</button>

  <script type="module">
    import init, { Counter } from "./pkg/wasm_counter.js";

    async function main() {
      await init();
      const counter = new Counter();

      const valEl = document.getElementById("value");
      document.getElementById("inc").onclick = () => {
        counter.increment();
        valEl.textContent = counter.value();
      };
      document.getElementById("dec").onclick = () => {
        counter.decrement();
        valEl.textContent = counter.value();
      };
    }

    main();
  </script>
</body>
</html>

运行一个静态服务器:

python3 -m http.server 8080

打开浏览器访问 http://localhost:8080,即可看到一个由 Rust 驱动的计数器应用。🎉


七、与 JavaScript 的互操作性

wasm-bindgen 支持直接使用 JavaScript API。例如,可以在 Rust 中调用浏览器的 alert

#[wasm_bindgen]
extern "C" {
    fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {} from Rust!", name));
}

Rust 编译后会生成绑定代码,允许你直接在 JS 中执行:

import init, { greet } from './pkg/wasm_counter.js';
await init();
greet('Steven');

八、性能测试:Rust vs JavaScript

我们编写一个简单的 Fibonacci 函数来测试性能:

#[wasm_bindgen]
pub fn fib(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fib(n - 1) + fib(n - 2),
    }
}

对应的 JavaScript 实现:

function fib_js(n) {
  if (n <= 1) return n;
  return fib_js(n - 1) + fib_js(n - 2);
}

在浏览器中运行 n = 40 测试:

实现方式

平均耗时

提升倍数

JavaScript

9.8 秒

1x

Rust WASM

1.7 秒

≈5.7x

Rust 版本几乎提速六倍,同时无类型错误、无 GC 抖动。


九、WASM Beyond Browser:边缘与云原生

WebAssembly 已经超越浏览器,成为新的云计算运行时标准。
Rust + WASM 在边缘计算中展现出惊人的灵活性:

场景

框架 / 平台

说明

边缘计算

Wasmtime / WasmEdge

快速、安全的沙箱执行环境

Serverless

Fermyon Spin

用 WASM 部署无服务器函数

容器替代

wasmCloud

微服务组件模型

数据流计算

Suborbital / Lunatic

分布式任务执行平台

Rust 的零运行时特性使其天然适配这些 WASM Runtime。
举例:使用 Wasmtime 直接运行 Rust 编译的 .wasm 文件:

wasmtime target/wasm32-unknown-unknown/release/app.wasm

十、结语:Rust + WASM = 下一代计算模型

Rust 与 WebAssembly 的结合不仅仅是“高性能前端”的尝试,而是一个全新的软件范式:

  • 性能跨越边界:系统级性能走进浏览器与边缘环境;
  • 安全可移植:沙箱执行模型防止内存越界;
  • 语言统一:Rust 可同时编译为原生二进制与 WASM;
  • 未来趋势:WASI 标准化后,WASM 将成为“云端通用运行时”。

Rust 是唯一一门既能写操作系统,又能安全运行在浏览器的语言。
在未来的分布式与多端世界中,Rust + WASM 将是“代码即计算单元”的最佳实现。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐