您的位置:首页 > Web前端 > JavaScript

关于WebAssembly的一些介绍和开发

2017-09-17 12:50 369 查看
近几年,WebAssembly在快速的成长中,被称为未来的web发展方向。
本文主要内容是关于WebAssembly,包括和asm.js的一些对比,以及WebAssembly的一些特性和开发方式。
本文主要内容来自Google I/O '17中Alex Danilo的关于WebAssembly的主题演讲。感兴趣的可以去YouTube看原文视频。


JavaScript性能瓶颈

首先,我们需要从JavaScript说起,JavaScript目前作为web端的中流砥柱,可以说是撑起了一片天下,加上最近火热的node.js,大有一统前后端的趋势。但其作为一门解释型语言,在大型项目中的运行速度实在是差强人意。通过下面这张图我们可以通过一个简单的“+”运算,来看看JavaScript引擎都需要做什么。



上图为JavaScript如何把执行加号,因为在JavaScript中,一个“+”的两边可能是任何类型的数据,并且两边的类型并不一定相等,所以在执行时候,引擎首先需要判断类型,然后再根据类型执行对应的操作,我们从上图中也可以看到,一个“+”的过程相当复杂。而对于现代引擎来说,已经很难去优化这部分过程,所有的都是必须的。

所以现在有很多关于这方面的研究,关于提升JavaScript的性能瓶颈。目前主要有两种思路:

一种是以typescript,JSX 为代表。比如typescript在编写的时候需要程序员指定变量的类型,和一门强类型语言一样,然后再编译成JavaScript,相当于把强类型编译成弱类型。

以及几个来自Mozilla的天才工程师发明了asm.js,asm最初的设计目标是在Emscripten中,将写好的c++转换成js中一个很小的子集,通过用类型标注,来识别变量类型,而js引擎会将这部分代码转换成更快的原生代码。

下面是一个示例:

//asm.js示例
function add1(x){
x = x|0;
return (x+1)|0
}
//通过x后面标注的|0,可以识别x是一个int类型变量。


关于上面两种方法,很快就发现第二种的潜力和速度是要明显优于第一种的。对于第一种,只是加快了现有的编译速度,比如JIT编译。但是对于第二种,却可以大大改变现在JavaScript的编译过程,甚至实现AOT。

随着几年的发展,人们发现asm.js的确对JavaScript性能提示有很好的效果。但是,asm也存在着缺陷,因为它并未标准化,导致它在不同浏览器上的支持不一样,导致了性能差异也很明显,有的浏览器对它支持不好。

所以,在Mozilla, Google, Microsoft, and Apple的联合下,对asm.js去粗取精,进行标准化,诞生了WebAssembly,WebAssembly并不是一种需要去写的语言,也没有人会去这么做,它可以说是一种编译目标。

首先我们需要清楚一件事情,如果想要极限的优化代码执行,让它运行的更快,减少无用中间过程, 就如上面的“+”操作,我们最终极的目标就是“+”能够直接被转换为一条简单CPU指令操作。而这个也是WebAssembly想要做的。

而WebAssembly目前可以以原生代码速度的1.2倍运行,这个数据看上去令人非常吃惊的。但它的确已经存在了,并且这项技术也已经被四个主流的浏览器引擎所支持。

过去对于web性能的提升

在正式介绍之前,我们可以回顾下以前提升web性能的一些方式。

在过去提升Web性能的方式主要是通过插件,比如flash和它的JIT。但是我们也知道这项技术在今天已经过时了,原因之一也是因为它的安全问题,哪怕是在沙盒环境中,它们的安全漏洞依旧存在。其次,这些插件对Web API的支持并不好。当然,最主要的一个原因应该是移动端的蓬勃发展,导致这些插件已再无用武之地。

再后来,是Google的Native Client计划。它的目标是将js编译后运行在web浏览器中。但是缺陷和明显,和web api的交互性弱,不支持dom对象,后来也产生了portable Native Client,但是因为安全原因实现太过困难,也没有浏览器会那么做。

与asm的对比

下面我们简单看看在V8引擎中,为什么WebAssembly会比asm更好,主要体现在优化引擎TurboFan参与 的阶段。

以上面的示例asm.js代码为例,我们看看这段代码在引擎中发生了什么。



首先浏览器对代码进行解析,分析词法环境进行,生成ast树。ast树是内存中你的程序的逻辑表示。不同浏览器对于接下来的步骤会有所不同,在v8中,引擎会根据生成的AST直接生成对应的机器码,这部分由V8的Full Compiler完成。事实上,这段解析js的过程已经是很快了,基本不再有可能去优化这个过程了。

在上面生成的是未经过优化的代码。接下来,在V8中会对部分代码(由上面的Full Compiler运行一段时间后得出的“热门”代码和那些运行较慢的代码)使用它的TurboFan优化引擎。对代码进行重新编译,从而大大提高效率。

对于asm.js,它会参与整个分析阶段,包括生成ast,生成机器码,找出那些使用“热门”的代码以及重编译等等,这些其实都是属于CPU周期,asm.js却需要全程参与。但如果是用WebAssembly,就如下图所示,WebAssembly会出现在最后阶段,这是因为WebAssembly在编译阶段已经完成了优化,所以在不需要再参与分析阶段。



所以,WebAssembly相比asm大大减小了优化编译时期的工作量。通过数据显示,而相比与asm.js,WebAssembly 的速度比asm.js快2/3(指的是运行时速度)。

WebAssembly介绍

下面,我们将要正式介绍WebAssembly。

关于WebAssembly,之前看过很多人问,有了WebAssembly是不是意味着我们不再需要去写JavaScript了,答案当然是NO。WebAssembly只是JavaScript的一个补充,它提供了一个途径,去让那些写C++,C或是rust code以及其他静态类型语言的人,把它们写的编译成一个模块,而这个模块可以被JavaScript调用,与JavaScript协同工作。

WebAssembly作为JavaScript的补充,提供了和c++一样的强类型机制,例如int32。有了这些强类型的机制,引擎就可以省去之前花费大量时间的类型处理,将JavaScript像C++一样进行AOT(静态编译),从而实现将JavaScript的速度提升到和原生代码一样的程度。

使用WebAssembly,你可以不受任何影响的使用所有的web API,所有的标准DOM函数以及API,当然,也有一些新的东西,比如32位的浮点数或是64位整数,以及添加的threas支持和SIMD(单指令多数据)。需要了解的是,WebAssembly 的执行堆是完全与WebAssembly 程序隔离的,所以你是无法干涉或者改变它的执行过程,这也是一个很重要的安全特性。

需要指出的一点是,WebAssembly 是无法访问任何的平台APIs。所以,你需要通过JavaScript本身与调解这一切,而WebAssembly 只需要去完成它本身能够做的,比如数值方面的工作。

WebAssembly 语言介绍

下面这张图展示了WebAssembly 的一些要素,数值类型与c++相同,并且在WebAssembly中,它们与c++一样同样是静态类型。操作方面,提供基本的四则运算,除此之外,也包括平方根,取整。



支持情况

而对于开发者所关心的支持情况,



我们可以看到,目前这项技术是被主流引擎厂商所支持,所以开发者不用担心支持情况。

WebAssembly 开发

现在开发者现在可以到webassembly官网去获得如何开发WebAssembly 的一些指导,先从一个hello World开始。这个网站包括了基本所有WebAssembly的内容,包括技术细节,API和DEMO。

作为开发 WebAssembly的工具 。目前有binarian,这也是新诞生一种工具,通过与emscripten一同协作来产生WebAssembly code。此外,也可以用其他工具比如GCC 。

接下来,当你有了一个c++文件,就可以通过相应的编译命令,得到两个文件,.js和.WASM。这个js文件便可以直接在浏览器中运行。

同时,也可以在WASM中调用js,包括一些DOM APIs,通过使用EM_ASM这个命令:

//CALL JS FROM WASM
#include<emscripten.h>
int main(){
EM_ASM(
const elt = document.getElementById("hello-world");
elt.innerText = "Hello World";
);
return 0;
}


当然,不仅限于Web API,你同样也可以可以在C++中导入你在js中定义的函数。

总结

以上就是关于webassembly的一些介绍,现在webassembly被称为未来web的发展方向。个人认为它是解决JavaScript性能瓶颈的出路,期待以后web能够给人们展示越来越炫酷和惊艳的页面。

开发资源:

WebAssembly 的主站,技术性最强

design repository,GitHub地址

w3c Group

示例:

关于WebAssembly ,一个动态实时视频渲染的例子,在WebAssembly 情况下,性能要比js高出80%或者更多。

与上面的是相关联的,是它的GitHub地址

一个来自google的调用WebGl做3D处理的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息