首页 > 代码库 > WebAssembly:随风潜入夜

WebAssembly:随风潜入夜

What?

  WebAssembly 是一种二进制格式的类汇编代码,可以被浏览器加载和并进一步编译成可执行的机器码,从而在客户端运行。它还可以作为高级语言的编译目标,理论上任何语言都可以编译为 WebAssembly。

  我们知道汇编语言就是机器码的一种直译版本,它是一套指令的集合,必须与特定机器匹配。WebAssembly 虽然也可以看成汇编代码,但有一点不同,它是与特定机器无关的,它的指令被称为虚拟指令,并非真正的处理器指令。也就是说 WebAssembly 是一个平台无关的通用编译目标,可以运行在各种设备上,包括手机和物联网。

  WebAssembly 起源于 Mozilla 的一个项目:ASM.js,这玩意儿简单的说就是 JS 的一个轻简版子集,去除了动态类型、对象、垃圾回收等损耗性能的部件。它的作用是成为 C/C++ 的编译目标,从而能将大中型游戏引入浏览器,事实证明效果不错。然而 ASM.js 毕竟仍然是 JS,它不具备原生代码的一些功能,如 SIMD、线程、共享内存等,因此 ASM.js 进一步发展,就成了 WebAssembly。

  WebAssembly 的实质是 AST,而非字节码(bytecode),使用 AST 的原因是因为 AST 比字节码更容易压缩,也更容易翻译。

  作为浏览器厂商四巨头(谷歌、苹果、火狐、微软)合作共谋的产物,WebAssembly 的应用前景不可小觑。

 

Why?

  随着高计算量 Web 应用(3D图形、游戏、VR等)的出现,JavaScript 的速度又一次显得不够用了。WebAssembly 的目的就是让浏览器多一种运行更快速的代码。

  WebAssembly 比 JS 快这是显然的,一个接近 native code,另一个是动态类型的解释型语言,完全没法比。简单比较一下 JS 和 WebAssembly 的运行时过程就知道 WebAssembly 究竟快在哪儿了:

技术分享

       WebAssembly 不仅运行更快,传输也更快,因为它是二进制格式的,压缩率更高,体积更小。引用 Opera CTO 罗志宇的说法,WebAssembly 就是对 JS 性能问题的终极填坑方案。

       在浏览器中引入 native code 的尝试其实早就有了,但是几乎没有一个成功的,无论是 Java Applet,还是谷歌的 Portable Native。Brendan Eich 对此的看法是,这些方案试图重建一个系统来替代 JS,这种革命式的改造在无权威的互联网世界是行不通的,因为 JS 已经在 web 端形成了自然垄断地位,如果仅仅为了改善性能问题,就彻底推翻重构,无异于削足适履,浏览器厂商是不干的。

  作为实用主义者,Brendan Eich 认为现实总是以渐进的方式改良,因此 WebAssembly 被设计为与 JS 协同使用,它既不会,也不可能替代 JS。

 

How?

  生成 WebAssembly 的方式有多种,可以直接手写,因为 WebAssembly 提供了文本形式,写起来跟汇编差不多。更通行的方式是将用其它语言——目前主要是静态语言(C、C++、Rust等)编写的代码编译成 WebAssembly(.wasm),编译工具最主要的是 LLVM。如果要支持动态语言,如 Python、Ruby 甚至 JS,那么编译器必须引入更多的扩展。

  LLVM 编译的基本工作机制是:首先使用一种针对特定语言的插件(类似于 webpack 中的 loader)将该语言编译为一种中间态形式(IR),然后再由 LLVM 对 IR 进一步编译、优化,从而得到.wasm。当然也有其它的编译工具,如 Emscripten、Binaryen 等。工具链的便捷程度是影响 WebAssembly 发展的一个重要因素。

技术分享

       得到 .wasm 文件之后怎么用呢?目前 .wasm 需要由 JS 引入后才能运行,JS 中有一个用于操作二进制代码的 API:ArrayBuffer,JS 使用 ArrayBuffer 加载 .wasm,然后调用编译方法,然后再创建实例。WebAssembly 还没有集成 Web API,要调用 Web API,就必须借助 JS。未来计划允许 WebAssembly 直接调用 Web API,并且让 .wasm 模块像 ES6 模块一样易于使用。

  目前 Chrome、FF、Edge、Safari 最新版都已支持 WebAssembly,对于不支持 WebAssembly 的浏览器,会有 polyfill 把 WebAssembly 重新翻译为 JavaScript。

 

Pros?

  1、WebAssembly 使得 web 应用具备了原生应用的性能;

  2、WebAssembly 提供了一种符合 W3C 标准的技术,从而可以取代私有的、非标的、安全性差的插件,如 flash 和 Silverlight;

  3、从古至今,浏览器只支持一种程序语言:JS,WebAssembly 使得有更多语言能够用于打造 web 应用;

  4、WebAssembly 是一个渐进式的方案,而非疾风骤雨,势不两立的革命,因此更具有现实可操作性。

 

Cons?

  现在还不好说,咱们拭目以待吧。

 

参考资料:

https://www.smashingmagazine.com/2017/05/abridged-cartoon-introduction-webassembly/#

https://medium.com/javascript-scene/why-we-need-webassembly-an-interview-with-brendan-eich-7fb2a60b0723

WebAssembly:随风潜入夜