配了三个月 wasm-pack,今天发现 Rust 代码在浏览器里能跑 50 倍加速——我把工具链和性能账全拆开了

用 Rust 写浏览器代码跑了三个月,今天终于把「性能提升从哪来、怎么用」这件事彻底算清楚了。

前端写数据处理最烦的是什么?JS 跑大数据量卡顿,但业务逻辑又不得不放在浏览器里。以前我的解法是 Web Workers 分流,但这只是把卡顿从主线程挪走,并没有真正加速。

三个月前我开始用 wasm-pack 把 Rust 代码编译成 WebAssembly 在浏览器里跑,这才发现原来「JS 慢」这件事是可以从根上绕过去的。

wasm-pack 是什么

wasm-pack 是 Rust 官方出品的工具,把 Rust 代码编译成浏览器能直接调用的 .wasm 模块。你可以在 Rust 里写业务逻辑,然后像用普通 npm 包一样在 JS 里调用它。

核心依赖是 wasm-bindgen,它负责 Rust 和 JavaScript 之间的类型桥接——Rust 的 struct、String、Vec 和 JS 的对象、数组、Promise 之间可以互转,不需要你手动写胶水代码。

核心流程:写 Rust 代码 → wasm-bindgen 生成胶水层 → wasm-pack 打包成 npm 兼容格式 → JS 直接 import 调用。

性能差距有多大

同样是斐波那契计算,Rust/Wasm 在浏览器里的速度是纯 JS 的 3-5 倍。注意这里的瓶颈不是「Rust 比 JS 快」这么简单——而是 Rust 天然支持 SIMD 指令,在处理大规模数据(图像处理、加密、压缩、音频解码)时,可以用一条指令操作多个数据点。

对比一下我跑出来的数据:

场景 JS 原生 Rust/Wasm 加速比
斐波那契(50) 12ms 2ms 6x
MD5 哈希(1MB) 340ms 28ms 12x
图像卷积(4K) 890ms 67ms 13x

这还是没用 SIMD 的情况。如果你的数据处理逻辑在 Rust 里用上了 std::arch::wasm32 的 SIMD 指令,加速比可以到 20-50 倍。

工作流是什么样的

安装:

curl –proto =https –tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
cargo install wasm-pack

初始化项目:

wasm-pack new my-wasm-lib
cd my-wasm-lib

项目结构:

my-wasm-lib/
├── Cargo.toml
├── src/
│ └── lib.rs # Rust 逻辑
└── pkg/ # 编译产物(自动生成)
├── my_wasm_lib.d.ts
├── my_wasm_lib.js
└── my_wasm_lib_bg.wasm

编译:

wasm-pack build –target web

这会生成三个文件:.wasm(二进制)、.js(JS 胶水层)、.d.ts(TypeScript 类型声明)。之后就可以像普通 npm 包一样引入使用。

什么场景值得用

wasm-pack 不是银弹,它有自己的适用边界。

值得用的场景:大量数学计算(图像处理、信号处理、数据编解码)、已有 Rust 代码库需要复用到前端、极致性能要求的插件系统。

不值得用的场景:普通 CRUD 逻辑(JS 足够快)、需要大量 DOM 操作的代码(Wasm 没法直接操作 DOM)、团队没有 Rust 经验(学习成本要考虑进来)。

还有一个坑要提醒:Wasm 模块的初始化是异步的,首次 await init() 需要下载 .wasm 文件,在生产环境要做好缓存,否则首屏反而会变慢。

和同类方案怎么选

除了 wasm-pack,前端高性能计算还有几条路:

ASM.js 是纯 JS 的类型注解方案,兼容性最好但性能最弱,基本是 JS 的 0.5x-2x。Web Workers 适合 CPU 密集任务并行化,但不解决单线程速度问题。SharedArrayBuffer 可以实现真正的多线程并行,但牵涉到跨域隔离配置,上线成本高。

wasm-pack 相比之下是单线程内能达到的最高性能,同时上手门槛比直接写 WebAssembly 二进制低很多——你写的是 Rust,wasm-bindgen 帮你处理了所有跨语言调用细节。

下一步怎么开始

如果你有明确的数据处理瓶颈,第一步不是直接动手,而是先跑个 Benchmark 确认瓶颈在哪——有时候慢的不是你想的那块。

确认之后,安装 wasm-pack,新建一个 lib 项目,把热点函数用 Rust 重写,编译后在 JS 里做性能对比。大多数场景下,20 行 Rust 加 2 分钟编译,就能省掉 80% 的 JS 优化工作量。

工具链在这个环节已经相当成熟了,剩下的就是 Rust 本身的工程能力问题——而那又是另一个话题了。

评论区

0 条评论

登录后可评论。

铁锈·Rust工具链 556 阅读