一、前言
自从JavaScript诞生开始,到现在开始变成流行的编程语言,背后的是web发展所推动的。web应用的变得更多更复杂,但是渐渐暴露出JavaScript的问题:
(1)语法太灵活导致开发大型web项目困难;
(2)性能不足满足一些场景的需要。
二、为什么需要WebAssembly
针对以上的问题,JavaScript出现了一些代替语言,比如:
(1)微软的TypeScript通过JS加入静态类型检查机制来改进js松散的语法,提升代码健壮性。
(2)谷歌的Dart则是为浏览器引入新的虚拟机去直接运行Dart程序以提升性能。
(3)火狐的asm.js则是取JS的子集,JS引擎针对asm.js做性能优化。
以上尝试各有优缺点。其中:
(1)TypeScript只是解决JS语法松散的问题,最后还是需要编译成JS去运行,对性能没有提升。
(2)Dart只能在chrome预览版中运行,无主流浏览器支持,用Dart开发的人不多。
(3)asm.js语法太简单,有很大限制,开发现率低。
三大浏览器巨头分别提出了自己的解决方案,互补兼容,这违背了web的宗旨,是技术规范统一让web走到今天,因此如果有一套新的规范去解决JS面临的问题就太好了。
于是webAssembly出现了,webAssembly是一种新的字节码格式,主流的浏览器已经支持webAssembly。和JS需要解释执行不同的是,webAssembly字节码和底层机器码很相似可快速装载运行,因此性能相对于JS解释执行大大提升。也就是说webAssembly并不是一门编程语言,而是一份字节码标准,需要用高级语言编译出字节码放到webAssembly虚拟机中才能运行,浏览器厂商需要做的是根据webAssembly规范实现虚拟机。
三、webAssembly原理
要弄清楚webAssembly原理,需要先搞清计算机运行原理。
电子计算机是由电子元件组成,为了方便处理电子元件只存在开闭两种状态,对于1和0,也就是计算机只认识1和0,数据和逻辑都需要由1和0表示,也就是可以直接装载到计算机中运行的机器码。机器码可读性极差,因此人们通过高级语言c,c++,Java,Go等编写再编译成机器码。
由于不同的计算机CPU架构不同,机器码标准有所差别,常见的CPU架构包括X86,AMD64,ARM,因此在由高级编程语言编程成可自行代码时需要指定目标架构。
webAssembly字节码是一种抹平了不同架构的机器码,webAssembly字节码不能直接在任何一种CPU架构上运行,但是由于非常接近机器码,可以非常快的被翻译为对应架构的机器码,因此webAssembly运行速度接近机器码,这听上去非常像java字节码。
相对于JS,webAssembly有以下优点:
(1)体积小。由于浏览器运行时只加载编译成的字节码,一样的逻辑比字符串描述的JS文件体积小很多。
(2)加载快。由于文件体积小,再加上无需解释执行,webAssembly能更快的加载并实例化,减少运行前的等待时间。
(3)兼容问题少。webAssembly是非常底层的字节码规范,制定好以后很少变动,就算发生变化,只需要从高级语言编译成字节码过程做兼容。可能出现兼容问题是JS和webAssembly桥接的JS接口。
每一个高级语言都去实现源码到不同平台的机器码的转换工作是重复的,高级语言只需要生成底层虚拟机(LLVM)认识的中间语言(LLVM IR),LLVM能实现:
(1)LLVM IR到不同CPU架构机器码的生成。
(2)机器码编译时性