WebAssembly 会杀死 JavaScript 吗?让我们找出答案(+ Live Demo) 🚀
Source: Dev.to
TL;DR 🧠
一个包含 WASM 与 JS 基准测试的小型实时演示以及 GitHub 仓库。
- 单独的 JavaScript 已经 非常快,对大多数任务来说完全够用。
- 在 大量计算 时,WASM 拥有 显著优势,即使没有 SIMD 等高级优化。
⚠️ 我故意没有对输入进行校验——请小心,浏览器标签页很容易被卡死。
Demo:
Repo:
我们到底该怎么写 WebAssembly 代码? 🤔
基础
编译成 WASM 的代码通常使用 低级语言 编写,例如:
- Rust
- Go
- C / C++
为什么不用 Python 或纯 JavaScript?
WebAssembly 不是原生 CPU 机器码。
它是一种 可移植的字节码格式,浏览器随后会 JIT‑编译成机器码——这与它们处理 JavaScript 的方式非常相似。
Python 或 JS 的主要问题并非“编译器太重”,而是:
- 动态类型
- 大型运行时
- 垃圾回收
- 不可预测的内存模型
WASM 设计围绕 简单、可预测的执行和内存模型,这更适合 Rust、C++ 等语言。(是的,WASM GC 已经存在并在演进,但在生产环境中仍未普及。)
为什么我选用了 Rust 🦀
在演示中我使用 Rust,主要因为它拥有 几乎为零的运行时,并且可以让你显式控制内存。
- 在 Windows 上也不难上手(只需安装 Visual Studio 工具链)。
- Rust 常被形容为 “TypeScript 的强化版”——对类型极其严格,根本没有
any。 - 所有权 与 借用 等概念帮助防止大量 bug。
如果想深入了解,dev.to 上有大量优秀的 Rust 文章。
编译到 WASM
编译过程相当直接,且可以集成到 CI/CD 流水线中。
仓库已经包含编译好的文件,方便你查看实际的 WASM 输出以及它是如何在 JavaScript 中被调用的。
何时使用 WASM,何时 JavaScript 更合适? ⚔️
你可以在演示中自行验证。基准测试代码已公开在 GitHub,确保没有任何作弊。
提醒: 输入值由你自行负责——很容易把浏览器标签页卡死。
JavaScript 真的很快 🏎️
WASM 确实快得惊人,但浏览器引擎作者也在不断努力。像 V8、SpiderMonkey 这样的引擎的 JIT 编译表现非常优秀。
如果你在编写普通的前端应用(简单的 CRUD、大量 DOM 交互),纯 JavaScript 往往 整体更快,即使涉及相对较重但直接的计算。
示例:矩阵乘法
n × n 矩阵乘法(返回单个数值,模 1 000 000 007)在 JS 中表现完全可以接受,且常常看起来比 WASM 更快。
原因在于 JS ↔ WASM 边界的开销——跨越次数越多、复制的数据越多,性能优势就会被侵蚀。

当 JS 开始失利 💥
在 真正的大规模计算 时情况会改变。
示例:阶乘取模
n! mod 1 000 000 007 让 JavaScript 明显慢于 WASM。虽然对这个小例子来说绝对耗时仍然很低,但想象一下:
- 物理仿真
- 数值求解器
- 大型统计模型
JavaScript 使用 IEEE‑754 双精度数;当数值非常大时必须切换到 BigInt,这非常 慢。而 Rust 则直接在 u64 上运算,导致性能差距巨大。
结果还会因以下因素而异:
- 浏览器
- JS 引擎
- 硬件
在我的机器上,Firefox 的差距比 Chrome 小一些。

图像处理怎么办? 🖼️
WASM 常被拿来做图像、视频、音频处理——确实可以非常强大。
然而,一个 非常简单的基准测试(对图像应用高斯模糊)显示 JS 完全压制了 WASM,因为整个 Uint8Array 必须复制进 WASM 内存。
只有当我构建了 完整的图像处理流水线 时,WASM 才开始占优:
- 连续应用多个滤镜
- 尽可能多的工作在 WASM 内部 完成
经验教训: “WASM 适合图像处理” 只有在 操作足够重 时才成立。(共享内存可以降低开销,但会增加复杂度。)
即便是处理数百万像素的高斯模糊,JS 也能出奇地快。

加分项:WASM 不是唯一的工具 🧰
其他 Web 技术有时也是完美的替代方案:
- Web Workers – 将繁重任务卸载到后台线程。
- OffscreenCanvas – 在主线程之外渲染图形。
- GPU 方案(WebGPU) – 利用 GPU 进行并行计算。
选择合适的工具取决于你要解决的具体问题。