js是严格的Javascript子集,合理的asm.js代码必须是合理的JavaScript代码
前面我们讲到会有新的技术出现,那么具体是什么技术呢?
出现了asm.js
为此,WebAssembly的前身asm.js就诞生了。js是严格的Javascript子集,合理的asm.js代码必须是合理的JavaScript代码,但反过来看,它就不合理了。和WebAssembly一样,asm.js不是为大家用一行手写的代码而设计的,asm.js是编译的目标。尽管其可读性比WebAssembly更好,但对开发者而言,它仍然是不可接受的。
例如,asm.js强制使用静态类型。
为何asm.js具有静态类型?由于类似于0|0,它代表的是Int,而+1.1代表的是Double,所以它代表的是Int。
asm.js无法解决所有问题
也许有人会怀疑,这个问题解决了没有?那么,为什么要使用WebAssembly?网络助手又解决了什么问题?你可以再看看上面ChakraCore引擎的结构图。不管asm.js如何处理静态类型的问题,它总是绕过Parser,绕过ByteCodeCompiler,这两步是JavaScript代码在引擎执行期间最耗时的。而且WebAssembly不需要这两个步骤。因此,WebAssembly比asm.js更快。
WebAssembly的诞生
2015年,我们迎来了WebAssembly。WebAssembly是经过编译器编译的小型代码,快速启动。完全脱离JavaScript语法,同时有沙盒执行环境。对于C/C++/Rust来说,WebAssembly也强制执行静态类型。
WebAssembly的优点
与asm.js相比WebAssembly的性能
下图是一款BenchMark,对比了UnityWebGL使用和不使用WebAssembly的开始时间,它提供给你作为参考。在FireFox中可以看到,WebAssembly和asm.js之间的性能差异是原来的2倍,Chrome之间的3倍,Edge之间的6倍。从侧面对比还可以看出,现在所有的主流浏览器都支持WebAssemblyV1(Node>=8.0.0)。
对比一下JavaScript
在使用create-react-app创建的一个新项目中,我自己对WebAssembly版本和原生JavaScript版本的递归无优化Fibonacci函数进行了对比,下图显示了当值为45、48和50时,这两个函数的性能对比。
从图表中可以看出,这是WebAssembly和JavaScript之间的一个实际性能对比。稳定性是JavaScript的两倍。
在大型项目中应用WebAssembly
还有许多例子可以在这里举出,如AutoCAD、GoogleEarth、Unity、Unreal、PSPDKit、WebPack等。用几句话来简单说一下。
AutoCAD
它是一款用于画图的软件,很久以来都没有Web版本,原因有二,其一,Web的性能确实不能满足其需要;第二,在WebAssembly还没有出现之前,AutoCAD是用C++来实现的,它的实现意味着要重写它所有的代码,成本非常高。
经过WebAssembly的出现,AutoCAD得以利用编译器,直接将沉淀超过30年的代码编译到WebAssembly中,同时性能得到了极大的提高,这是基于以前常见的Web应用程序的。正因为这样,AutoCAD才能够把它的应用从Desktop转移到Web里面。
随着学习的加深,我们了解了WebAssembly基础知识和应用,后面还会讲解其他的知识。