- 后端
- 文档
- 教程
【免费下载链接】system-design-101
Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.
导读:本文以 System Design 101 仓库中的 Running C, C++, or Rust in a Web Browser 一文为核心骨架,系统讲解 WebAssembly(WASM)如何让原生 C/C++/Rust 代码在浏览器中运行、为什么它能获得接近原生的性能,以及它如何打开云原生与边缘计算的更多可能。读完本文,你将理解 WASM 的核心价值、与传统 JavaScript 的性能差异,以及它在复用现有代码库与 Serverless 场景中的实战思路。
什么是 WebAssembly(WASM)?
WebAssembly(简称 WASM)是一种可以在 Web 浏览器中运行的二进制指令格式,它既是一种可移植的编译目标,也是一套沙箱化的执行环境。它之所以吸引大量关注,核心原因在于:
- 它让非 JavaScript 语言编写的代码能够运行在浏览器中;
- 它的执行性能接近原生代码,远超传统解释执行的 JavaScript;
- 它允许开发者复用已经用 C/C++/Rust 等语言开发好的成熟代码库,而不是在浏览器里重写一遍。
原文档给出的图示展示了这一核心流程:把用 C/C++/Rust 编写的原生代码编译成 WASM 二进制,再由浏览器加载并执行。
为什么传统浏览器只能运行 JavaScript,且性能受限?
历史上,Web 浏览器中唯一可以编写业务逻辑的编程语言是 JavaScript。仓库中的 How does Javascript Work? 一文明确指出,JavaScript 是一种解释型语言:
"JavaScript code is executed by the browser or JavaScript engine rather than being compiled into machine language beforehand... Modern engines such as V8 utilize Just-In-Time (JIT) technology to compile code into directly executable machine code."
也就是说,JavaScript 在运行时才由浏览器引擎逐段解释或 JIT 编译,因此它的性能无法与 C/C++ 这类编译型语言相提并论。仓库中的 How Do C++, Java, Python Work? 一文给出了更根本的对比:
- 编译型语言(C、C++、Go):由编译器一次性编译成机器码,之后 CPU 直接执行;
- 字节码语言(Java、C#):先编译成字节码,再由虚拟机(如 JVM)执行,可通过 JIT 加速;
- 解释型语言(Python、JavaScript、Ruby):运行时由解释器逐行解释,不经过预先编译。
该文给出的结论是:"Compiled languages in general run faster than interpreted languages."(编译型语言总体上比解释型语言运行更快。)
正是这种"浏览器 = JavaScript = 解释执行"的约束,让许多对性能敏感的代码(视频编解码、图像处理、物理引擎、加密算法等)长期无法进入浏览器端。WASM 的出现打破了这一边界。
WASM 如何让 C/C++/Rust 代码在浏览器中运行?
核心思路是:把原生代码编译成 WASM 字节码,而不是直接编译成特定 CPU 的机器码。编译产物是一个.wasm文件,浏览器通过标准化的WebAssemblyAPI 加载并实例化它,然后在沙箱中执行。
一条典型的编译链路如下:
- 编写原生代码:使用 C、C++ 或 Rust 编写库或应用逻辑;
- 交叉编译到 WASM:使用 Emscripten(C/C++ 工具链)或 wasm-bindgen / wasm-pack(Rust 工具链)把源码编译为
.wasm模块; - 浏览器加载:通过
fetch获取.wasm文件,调用WebAssembly.instantiate或WebAssembly.instantiateStreaming完成编译与实例化; - JavaScript 桥接:通过导出的函数接口,JavaScript 可以直接调用 WASM 模块中的原生函数,实现跨语言协作。
从架构上看,WASM 模块运行在独立的沙箱中,与宿主环境(DOM、网络等)通过导入/导出接口交互,因此它既能获得接近原生的计算性能,又能保持 Web 平台的安全模型。
近原生性能:为什么 WASM 能接近原生代码?
WASM 的性能优势来自它设计的底层特性:
- 二进制格式,直接交给引擎的编译管线:WASM 字节码可以高效地转换为机器码,避免了 JavaScript 那样繁重的解析与优化开销;
- 静态类型与显式内存管理:WASM 的指令集是静态类型的,内存模型明确(基于线性内存),引擎更容易生成高质量的优化代码;
- 接近机器指令集的语义:WASM 指令与真实 CPU 指令的映射关系非常直接,因此编译出来的机器码与原生编译结果差距很小。
需要注意的是,这并不意味着 WASM 在所有场景下都"等于"原生性能——跨模块边界(WASM 与 JavaScript 之间的调用)仍存在开销,但在纯计算密集型任务中,WASM 的表现可以非常接近原生代码。原文档使用"near-native performance"(接近原生性能)来描述这一特性,这一表述是准确的。
典型应用:在浏览器中运行视频编解码库
原文档给出的一个关键例子是:在浏览器中运行用 C++ 编写的视频编码/解码(video encoding/decoding)库。
这在传统浏览器环境下几乎无法实现——视频编解码是高度计算密集的任务,纯 JavaScript 实现不仅开发成本高,性能也无法达到实时要求。而借助 WASM:
- 现有 C++ 编解码库(如 x264、FFmpeg 等)可以被编译为 WASM 模块直接运行在浏览器中;
- 用户无需安装任何插件或原生应用,打开网页即可完成视频的编码、解码与处理;
- 成熟、经过长期打磨的 C/C++ 代码库得以复用,避免了用 JavaScript 重写的巨大成本。
这只是一个代表。同样的思路可以推广到图像处理、音频合成、数据库引擎、加密解密、CAD 建模、游戏物理引擎等几乎所有"原生代码 + 浏览器运行"的组合场景。
WASM 对云原生与边缘计算的启示
原文档特别强调,WASM 为云计算和边缘计算打开了大量新的可能性:
1. 更轻量的 Serverless 运行时
传统 Serverless(如函数即服务)通常以容器或虚拟机为隔离单元,冷启动时间长、资源占用大。WASM 模块体积小、启动快、内存占用低,可以做到毫秒级实例化。原文档指出,借助 WASM 可以"run serverless applications with fewer resources and instant startup time"(以更少的资源、瞬时启动时间运行 Serverless 应用)。
2. 多语言统一的计算平台
WASM 不绑定某一种语言。用 C/C++/Rust 甚至其他语言编写的代码,都可以编译成 WASM 在统一的运行时上执行。这让平台团队可以构建"一套运行时、多种语言"的边缘或云节点,而无需为每种语言维护独立的运行时环境。
3. 边缘节点的资源约束
边缘计算节点通常资源有限(CPU、内存、带宽均受约束)。WASM 模块的紧凑体积与低资源消耗,使其非常适合部署在边缘节点上,将计算逻辑推近用户,从而降低延迟。
需要说明的是,这些价值描述来自原文档对 WASM 应用前景的阐述,属于合理的工程推演,而非对具体产品性能的承诺——在落地时,WASM 运行时的具体性能表现仍需结合实际场景验证。
从 System Design 视角看 WASM 的取舍
结合本仓库以"用可视化与简单语言解释复杂系统"的定位,在系统设计层面,WASM 引入的核心权衡值得记住:
| 维度 | 收益 | 代价 |
|---|---|---|
| 性能 | 接近原生的计算性能,适合计算密集型任务 | 与 JavaScript 跨边界调用存在开销 |
| 复用 | 可直接复用 C/C++/Rust 成熟代码库 | 需要额外的工具链(Emscripten、wasm-pack 等)与编译配置 |
| 安全 | 沙箱执行,保持 Web 安全模型 | 内存模型为显式线性内存,开发约束与 Web 环境不同 |
| 分发 | 单文件二进制,体积小、加载快 | 需要与 JS 桥接层配合才能访问 DOM 与浏览器 API |
| 部署 | 适合 Serverless 与边缘计算,启动快、资源省 | 生态与调试工具仍在持续演进中 |
小结
回到原文档的核心问题:能在浏览器中运行 C/C++/Rust 吗?答案是可以——通过 WebAssembly。WASM 让浏览器不再是 JavaScript 的"独占地盘",而是可以承载编译型原生代码的通用执行环境:
- 传统浏览器只有 JavaScript,且因解释执行而性能受限;
- WASM 将 C/C++/Rust 等原生代码编译为可移植的二进制模块,在浏览器中以接近原生的性能运行;
- 典型案例是视频编解码等计算密集型 C++ 库直接跑在浏览器中;
- 更进一步,WASM 以更少的资源和瞬时启动时间,为 Serverless 与边缘计算提供了新的运行时选择。
如果你希望进一步理解本文涉及的语言执行模型差异,可以继续阅读仓库中的 How Do C++, Java, Python Work? 与 How does Javascript Work?;浏览器如何解析与渲染页面可以参考 How Browsers Render Web Pages。
- 后端
- 文档
- 教程
【免费下载链接】system-design-101
Explain complex systems using visuals and simple terms. Help you prepare for system design interviews.
相关推荐
Gumbo-Parser与WebAssembly:如何在浏览器中运行C语言HTML解析器
Gumbo Parser与WebAssembly:如何在浏览器中运行C语言HTML解析器 在现代Web开发中,HTML解析是一个基础但至关重要的任务。Gumbo
后端CoreRT WebAssembly完整指南:如何将C代码编译成Wasm在浏览器中运行
CoreRT WebAssembly完整指南:如何将C 代码编译成Wasm在浏览器中运行 想要在浏览器中运行C 代码吗?🚀 CoreRT WebAssembl
GDevelop WebAssembly应用:C++核心代码的浏览器运行方案
GDevelop WebAssembly应用:C++核心代码的浏览器运行方案 引言:游戏引擎的Web革命 还在为游戏引擎的跨平台部署而烦恼吗?GDevelop通
游戏开发桌面应用前端低代码
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考