跨端技术的下半场:为什么 Wasm 正在改变游戏规则?

22 阅读4分钟

今天讲讲跨端开发的一些事儿。

聊到跨端开发,大家脑子里跳出来的第一反应大概率还是 WebView 套壳,或者是像 React Native、Flutter 这种“原生渲染”派系。

过去这些年,我们总在“开发效率、多端一致性、原生性能”这个不可能三角里反复横跳。但说实话,现在的 Web 场景早就不是画画页面那么简单了。当 Adobe 把 Premiere 搬上浏览器,当工业级 CAD 甚至 3A 游戏开始在线运行,传统的 JavaScript 难免显出疲态。这时候,WebAssembly(简称 Wasm,webassembly.org )进场了。我觉得它不只是个补丁,更像是直接把跨端开发的“性能天花板”给拆了。

别再聊“翻译”代码了,现在是算力的直接平移

以前我们做跨端,本质上是在玩“运行时”的平衡游戏。JS 框架再怎么优化,也绕不开 V8 引擎解析时的开销,一旦遇上密集的数学运算或者图像处理,那种内存抖动和卡顿感,懂的人都懂。Flutter 倒是聪明,自写了一套 Skia 引擎来画 UI,但逻辑层还是被困在 Dart 生态里。

Wasm 的逻辑完全跳出了这个圈子。

它把自己定义成一种低级的类汇编格式。简单来说,你不用再去想怎么把 C++ 或者 Rust 代码“翻译”成 JS,而是直接把这些硬核语言写的成熟模块,编译成二进制丢给浏览器运行。这已经不是语法转换了,这是直接把原本属于桌面的“工业级算力”原封不动地平移到了 Web 端。

为它是性能敏感型应用的“救命稻草”?

在我的观察里,Wasm 真正能改变规则,全靠它把那些“不确定性”给抹平了。

最直观的就是性能。JavaScript 执行起来像是个严谨但繁琐的翻译官,要经过解析、编译、优化一堆流程。Wasm 则是拿来即用的二进制流,指令路径极短。在处理矩阵运算或加解密这种“累活”时,它跑起来的速度往往能比 JS 快出几个数量级。

更让我心动的是它对内存的处理。Wasm 运行在一个线性的内存空间里,这就不存在 JS 那种让人头疼的垃圾回收(GC)随机暂停。如果你在写一个需要高帧率的 3D 渲染引擎或者音频合成器,这种“确定性”简直是救命的。

而且,它还顺手解决了生态鸿沟的问题。如果你手里有一个打磨了十年的 C++ 算法库,以前想移植到 Web 端几乎要掉一层皮。现在,套上 Emscripten 或者 Rust 的编译器,它就能在全平台跑起来。技术本来就应该是创意的延伸,而不是拖后腿的束缚。

看看那些已经“偷偷”吃螃蟹的人

这些变化不是实验室里的臆想,很多重头产品已经悄悄完成了重构。

比如大家都在用的 Figma,它之所以能丝滑地处理万级图层,核心就是那套基于 C++ 的渲染引擎通过 Wasm 跑在了浏览器里。再看现在的剪映 Web 版,或者是 B 站的视频投稿工具,背后处理编解码的脏活累活,其实都是 Wasm 在扛。

最近我也在琢磨 AI 的边缘化部署。现在的手机算力这么过剩,与其在昂贵的 GPU 服务器上烧钱,不如利用 Wasm 把量化后的模型直接丢到客户端去跑。既省了钱,又保护了用户隐私,这才是正经的演进方向。

还没到开香槟的时候

当然,现在的 Wasm 也不是全能的。

我在实践中发现,它和 JS 之间的数据传输其实是有开销的。如果你的应用只是简单的按钮交互,强行上 Wasm 反而有种“杀鸡用牛刀”的尴尬。再加上调试二进制模块确实比看 JS 源码痛苦得多,这对开发者的底功要求更高了。

此外,虽然 Chrome 跑得很欢,但在一些老旧的移动端 WebView 里,Wasm 的线程支持和向量指令(SIMD)还是会有兼容性的小坑。

一些碎碎念

我一直觉得,Wasm 的出现并不是为了干掉 JavaScript,它是来收编那些 JS 真的搞不定的“计算硬骨头”的。

往后看,跨端应用的架构大概率会演变成“JS 负责颜值(UI),Wasm 负责大脑(核心算法)”。这种混合模式真正实现了一套核心代码走天下。

作为一个技术人,如果现在还不去接触 Rust 或 Wasm,可能真的会错过这一波底层的范式转移。毕竟,谁不想先人一步看到未来呢?

微信公众号:Next Tech研究局

站在前端与 AI 的交叉口,分享最好用的工具与最前沿的跨端实践。