上一篇文章分析到最后,JS性能瓶颈归根结底是由于Javascript被设计为了一种动态类型语言,编译器无法在编译之前获悉变量的确切类型。因此各大互联网巨头都在为提升Javascript性能进行着不懈地努力,并逐渐形成了两大阵营。

JS性能优化两大阵营

Javascript的超集(superset)与 Javascript的子集(subset)。

wasm由来 - 图1

JS的超集(superset)**

一方以Google / Microsoft / Facebook为首,主张实现Javascript的超集(superset),说白了就是创造一种新语言,在兼容Javascript的基础上增加各种关键字,让开发者显式指定变量类型,从而转变成一种静态类型语言。微软的TypeScript就是一个典型范例,显然,这会增加开发者的学习成本。

asm.js

另一方Mozilla基金会旗下的Firefox则另辟蹊径,提出了一种Javascript的子集(subset),取名asm.js。这个asm.js只支持两种数据类型:

  • 32位带符号整数
  • 64位带符号浮点数

其他类型比如字符串、对象、布尔值什么的统统作为二进制数据通过TypedArray的形式进行访问。

WebAssembly的前身,asm.js是一个Javascript的严格子集,合理合法的asm.js代码一定是合理合法的JavaScript代码。asm.js不是用来给各位用手一行一行撸的代码,asm.js是一个编译目标。通常的做法是使用C/C++这样的静态类型和手动回收内存的语言编写程序,然后使用编译器将编写的程序编译为asm.js。Javascript程序员不需要学习任何新语法,就可以使用静态类型的语言了。Javascript引擎可以针对asm.js进行优化,根据测评,asm.js的运行效率可以接近native代码的50%!

asm.js不能解决所有的问题

无论asm.js对静态类型的问题做的再好,它始终逃不过要经过Parser,要经过ByteCode Compiler,而这两步是JavaScript代码在引擎执行过程当中消耗时间最多的两步。

asm.js的威力还不止于此,有一个叫Emscripten的开源项目,甚至可以把我们所熟悉的各种强类型语言都转换成asm.js!具体来说,Emscripten先使用LLVM的编译器前端把源码编译成LLVM字节码,然后再通过编译器后端把字节码转换成asm.js。也就是说,我们用C/C++或者Go写的程序,不需要任何改动,只需要用Emscripten编译一下,就可以在Web端运行!这实在是太激动人心了。

WebAssembly横空出世

上面介绍了asm.js的种种优点,各大互联网巨头自然不会熟视无睹。终于,Google、Microsoft、Apple、Mozilla这四大家族一致觉得asm.js这个方法有前途,干脆坐下来谈一谈,标准化一下,这样大家就都可以用了。
wasm由来 - 图2

WebAssembly是一种可以使用非JavaScript编程语言编写代码并且能够在浏览器上运行的技术方案,实际上,是一种新的字节码格式。