235-关于WebAssembly
优点缺点高性能、跨平台、安全调试困难、编译流程复杂、JS 与 Wasm 通信成本WebAssembly 是让浏览器支持更多“原生级”能力的关键技术,未来在AI、图形渲染、音视频处理、游戏、甚至数据库等领域都将越来越重要。
WebAssembly(缩写为 Wasm)是一种可以在 Web 浏览器中高性能运行的二进制指令格式,它是一种低级编程语言的编译目标,可由例如 C/C++、Rust 等语言编译生成,然后在浏览器中运行。
你可以把 WebAssembly 理解成一种能让原本不能运行在浏览器里的“高性能程序”也能在浏览器里跑的技术。
一、为什么需要 WebAssembly?
JavaScript 是浏览器中唯一的编程语言,但是:
-
JavaScript 是解释执行,性能相对较低;
-
一些需要高性能的程序(比如视频编解码、图形渲染、游戏引擎、机器学习等)用 JS 实现比较吃力;
-
有很多现成的 C/C++ 库,没法在 Web 中复用。
所以,WebAssembly 就出现了:
它允许我们把 C/C++/Rust 等编译型语言编译成 WebAssembly,然后在浏览器中运行,性能接近原生(接近 C++ 的速度)。
二、WebAssembly 的核心特点
特点 | 描述 |
---|---|
高性能 | 近乎原生的执行速度 |
安全 | 在浏览器沙盒中执行,不会破坏用户环境 |
可移植 | 与平台、架构无关,跨浏览器、跨系统运行 |
与 JS 协同 | 可以与 JavaScript 相互调用 |
三、WebAssembly 基本架构
-
源代码(C/C++/Rust)
-
→ 编译器(比如 Emscripten、Rust 的
wasm32-unknown-unknown
) -
→ WebAssembly 模块(
.wasm
文件) -
→ 在浏览器中通过 JavaScript 加载
.wasm
模块 -
→ 调用和交互(JS ⇄ Wasm)
四、实战教程:用 C 编写 WebAssembly
下面是一步一步从写代码到在网页中运行的完整过程:
1. 安装 Emscripten(C/C++ 到 Wasm 编译器)
✅ 安装步骤(Ubuntu/macOS/Linux)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
如果你是 Windows,可以用 Git Bash 安装,或用官方安装器。
2. 编写 C 代码
文件名:hello.c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
printf("WebAssembly loaded\n");
return 0;
}
3. 编译成 WebAssembly
emcc hello.c -o hello.html
这个命令会生成:
-
hello.html
:测试用 HTML 页面 -
hello.js
:JS glue 代码 -
hello.wasm
:WebAssembly 二进制模块
4. 启动本地服务器
因为浏览器不允许直接用 file://
访问 .wasm
文件,我们要开一个本地服务器:
emrun --no_browser --port 8080 .
然后在浏览器中打开:
http://localhost:8080/hello.html
你会看到控制台输出:
WebAssembly loaded
五、使用 WebAssembly 与 JavaScript 交互
我们可以用 JavaScript 来加载 .wasm
模块并调用其中的函数。
示例:JS 加载 .wasm
文件并调用 add(a, b)
// add.c
int add(int a, int b) {
return a + b;
}
编译:
emcc add.c -s WASM=1 -s "EXPORTED_FUNCTIONS=['_add']" -s EXPORTED_RUNTIME_METHODS='["cwrap"]' -o add.js
HTML 示例:
<!DOCTYPE html>
<html>
<body>
<h1>WASM Add Example</h1>
<script src="add.js"></script>
<script>
Module.onRuntimeInitialized = function () {
const add = Module.cwrap('add', 'number', ['number', 'number']);
console.log("3 + 4 =", add(3, 4));
};
</script>
</body>
</html>
💡
cwrap
是 JS 调用 C 函数的封装器。
六、用 Rust 编写 WebAssembly(更现代、更安全)
1. 安装 Rust 工具链
curl https://sh.rustup.rs -sSf | sh
rustup target add wasm32-unknown-unknown
2. 新建项目
cargo new wasm-demo
cd wasm-demo
3. 编辑 Cargo.toml
[package]
name = "wasm-demo"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
4. 编写代码 src/lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
5. 编译成 WebAssembly
wasm-pack build --target web
生成 pkg/
文件夹,里面有:
-
.wasm
文件 -
.js
文件(自动封装)
6. 在网页中使用
<script type="module">
import init, { greet } from './pkg/wasm_demo.js';
async function run() {
await init();
console.log(greet("WebAssembly"));
}
run();
</script>
七、调试与工具
-
🔧 wasm-pack:用于构建 Rust 项目的 WebAssembly 模块;
-
🔬 wasm2wat:把 .wasm 转换成 .wat(可读的文本格式);
-
🛠 WebAssembly Studio:在线 WebAssembly IDE(https://webassembly.studio/);
-
🧪 Chrome DevTools 支持调试 Wasm;
-
🔍 Firefox Nightly 支持逐步调试 Wasm。
八、使用场景举例
场景 | 用法 |
---|---|
游戏引擎 | Unity / Unreal 可导出为 WebAssembly |
图像处理 | 用 C 编写图像处理算法,在浏览器中实时处理 |
音视频编解码 | ffmpeg 可用 WebAssembly 编译 |
区块链 | 区块链智能合约(如 Polkadot)使用 WebAssembly |
数学库 | 机器学习 / 科学计算使用高性能 C 库在浏览器运行 |
九、总结
优点 | 缺点 |
---|---|
高性能、跨平台、安全 | 调试困难、编译流程复杂、JS 与 Wasm 通信成本 |
WebAssembly 是让浏览器支持更多“原生级”能力的关键技术,未来在 AI、图形渲染、音视频处理、游戏、甚至数据库 等领域都将越来越重要。
更多推荐
所有评论(0)