WebAssembly 初探

Chrome Dev Summit 2018

今年 11.12 到 11.13 是 Chrome Dev Summit 2018 开发者大会,有许多来自 Google 的工程师做了各种有趣的 Sessions 来分享他们对前沿技术的探索和展望,而这些研究关系到一个共同的目标:将 Web 打造得更好。

其中有一个 Webassembly Session(以下简称 Wasm)我觉得很有价值,而且这项技术关乎到 Web 开发的未来,故以此为参考,和读者们分享一下我对这项技术的看法。

该来的终究还是会来的

熟悉 JavaScript(以下简称 JS)的人应该都知道它的几个明显缺点:

  • 这是一个为非专业编程人员和设计师打造的解释型语言,而且它很慢
  • 这是一个没有类型的语言,它的解释器需要进行大量的类型判断,从而导致它更慢
  • Web 的使用场景正变得日益复杂,JS 已逐渐达到性能瓶颈,而它是浏览器目前唯一认可的语言
  • ……

这么些年来,包括 Mozilla、Google、Apple、Microsoft 在内的各大开发商为了解决这些历史遗留问题,不得不制造很多 “轮子” 来面对现状。

例如 Google 于 2009 年在 V8 引擎中引入了 JIT(Just In Time Compiling)技术,将 JS 瞬间提升了 20 到 40 倍速度,但很快 JIT 带来的性能提升就被榨干了。

Microsoft 开发了一个叫 TypeScript 的语言,同时也是 JS 的一个严格超集,提供了可选的静态类型和基于类的面向对象编程,用来解决 JS “弱类型” 导致的编译性能问题。

Mozilla 开发了 Asm.js 作为中间语言,允许开发者采用 C 等编程语言编写 Web 应用,这一方案由于其接近 Native 的强大性能引起了各大厂商的注意,并为后来 WebAssembly 的诞生奠定了基础。尤其需要强调的是,这一方案得到了各大厂商的一致赞同!

Wasm

那么 Wasm 又有哪些特点呢?在这场 Session 的开头,PM Thomas Nattestad 给出了总结:

  • 这是一个为 Web 打造的全新语言
  • 不会替代 JS,但是能解决一些 JS 存在的问题
  • 提供接近 Native 的高效性能及稳定性
  • 四大主流浏览器已经开始实验性地支持 Wasm

它不是门用来编写的语言

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. -- webassembly.org

展开来说,Wasm 是一门低级的类汇编语言。它有一种紧凑的二进制格式,使其能够以接近原生性能的速度运行,并且为诸如 C++ 和 Rust 等拥有低级的内存模型语言,提供了一个编译目标以便它们能够在网络上运行。

所以实际上我们编写的仍然是相对更高级的语言,而不是 Wasm 本身。

对 JS 以外的语言友好

前面说到,JS 的设计缺陷导致它不适合处理复杂的需求,而在 Wasm 的帮助下,这个问题得到了妥善解决而且已经得到了实际应用,例如:

应用场景越复杂意味着代码量越大,所以当浏览器需要加载一个几十甚至上百 MB 的 Wasm 时,Streaming Compile 就能有效地缩短加载时间,同时迅速地将其转换为机器汇编代码。

另外,当加载对象为 JS 代码时,浏览器会等待整个 .js 下载完后,才将其递交给编译器执行,此时的编译对象是一个文件。而 Wasm 代码则会在下载的同时被编译,此时的编译对象是代码片段。两者的速度差异可想而知。

.Net、Ruby、Golang

好消息是,现在有许多开发者社区正在积极地将不同的编程语言对接到 Wasm 环境中,例如 Go、Perl、Python、Ruby、Kotlin、PHP、.Net 等等,但由于各种各样的原因,目前只有 Rust、C、C++ 三门语言能对 Wasm 拥有较完整的支持。

一点不成熟的看法

无论当下 JS 生态的发展如何,它不会因为 Wasm 的出现而消失,Wasm 也远没有我们期待的那么全能。从应用角度来说,它起到了与 JS 相辅相成的作用,让其它编程语言的开发者能将更多可能性带到 Web 中来。如果让我用一句话来描述 Wasm 目前的境况,五个字,任重而道远。

关于技术上的细节,我暂时还没深入研究,回头再另起一篇详细介绍。

推荐阅读