WebAssembly 3.0 - 在浏览器中运行 Rust 代码

WebAssembly 3.0 带来了重大改进。本文将教你如何在浏览器中运行 Rust 代码。

环境准备

安装 Rust

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

安装 wasm-pack

1
cargo install wasm-pack

创建 Rust 项目

1
2
cargo new --lib wasm-demo
cd wasm-demo

配置项目

编辑 Cargo.toml

1
2
3
4
5
[lib]
crate-type = ["cdylib"]

[dependencies]
wasm-bindgen = "0.2"

编写 Rust 代码

编辑 src/lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
use wasm_bindgen::prelude::*;

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

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

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

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

编译

1
wasm-pack build --target web

创建网页

创建 index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebAssembly 3.0 Demo</title>
</head>
<body>
<h1>WebAssembly 3.0 Demo</h1>

<div>
<input type="text" id="name" placeholder="你的名字">
<button onclick="doGreet()">打招呼</button>
</div>

<div>
<input type="number" id="fibNum" placeholder="数字">
<button onclick="calcFib()">计算斐波那契</button>
<p id="fibResult"></p>
</div>

<div>
<input type="number" id="num1" placeholder="数字1">
<input type="number" id="num2" placeholder="数字2">
<button onclick="calcAdd()">相加</button>
<p id="addResult"></p>
</div>

<script type="module">
import init, { greet, fibonacci, add } from './pkg/wasm_demo.js';

async function run() {
await init();

window.doGreet = function() {
const name = document.getElementById('name').value;
greet(name);
};

window.calcFib = function() {
const n = parseInt(document.getElementById('fibNum').value);
const result = fibonacci(n);
document.getElementById('fibResult').textContent = `结果: ${result}`;
};

window.calcAdd = function() {
const a = parseInt(document.getElementById('num1').value);
const b = parseInt(document.getElementById('num2').value);
const result = add(a, b);
document.getElementById('addResult').textContent = `结果: ${result}`;
};
}

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

运行

启动一个本地服务器:

1
python -m http.server 8080

访问 http://localhost:8080

性能对比

计算斐波那契数列(第 40 项):

  • JavaScript: 约 1200ms
  • WebAssembly: 约 400ms

总结

WebAssembly 3.0 让我们能在浏览器中运行高性能的 Rust 代码。它非常适合计算密集型任务。