WebAssembly 系列(六)WebAssembly 的如今与将来

做者:Lin Clark <br/>
编译:胡子大哈 html

翻译原文:http://huziketang.com/blog/posts/detail?postId=58ce7fd3a6d8a07e449fdd26 <br/>
英文原文:Where is WebAssembly now and what’s next?react

转载请注明出处,保留原文连接以及做者信息git


本文是关于 WebAssembly 系列的第六篇文章(本系列共六篇文章),也同时是本系列的收尾文章。若是你没有读先前文章的话,建议先读这里。若是对 WebAssembly 没概念,建议先读这里(中文文章)github

2017 年 2 月 28 日,四个主要的浏览器一致赞成宣布 WebAssembly 的MVP 版本已经完成,它是一个浏览器能够搭载的稳定版本。web

它提供了浏览器能够搭载的稳定核,这个核并无包含 WebAssembly 组织所计划的全部特征,而是提供了可使 WebAssembly 稳定运行的基本版本。浏览器

这样一来开发者就可使用 WebAssembly 代码了。对于旧版本的浏览器,开发者能够经过 asm.js 来向下兼容代码,asm.js 是 JavaScript 的一个子集,全部 JS 引擎均可以使用它。另外,经过 Emscripten 工具,你能够把你的应用编译成 WebAssembly 或者 asm.js。数据结构

尽管是第一个版本,WebAssembly 已经能发挥出它的优点了,将来经过不断地改善和融入新特征,WebAssembly 会变的更快。并发

提高浏览器中 WebAssembly 的性能

随着各类浏览器都使本身的引擎支持 WebAssembly,速度提高就变成天然而然的了,目前各大浏览器厂商都在积极推进这件事情。函数

JavaScript 和 WebAssembly 之间调用的中间函数

目前,在 JS 中调用 WebAssembly 的速度比本应达到的速度要慢。这是由于中间须要作一次“蹦床运动”。JIT 没有办法直接处理 WebAssembly,因此 JIT 要先把 WebAssembly 函数发送到懂它的地方。这一过程是引擎中比较慢的地方。工具

按理来说,若是 JIT 知道如何直接处理 WebAssembly 函数,那么速度会有百倍的提高。

若是你传递的是单一任务给 WebAssembly 模块,那么不用担忧这个开销,由于只有一次转换,也会比较快。可是若是是频繁地从 WebAssembly 和 JavaScript 之间切换,那么这个开销就必需要考虑了。

快速加载

JIT 必需要在快速加载和快速执行之间作权衡。若是在编译和优化阶段花了大量的时间,那么执行的必然会很快,可是启动会比较慢。目前有大量的工做正在研究,如何使预编译时间和程序真正执行时间二者平衡。

WebAssembly 不须要对变量类型作优化假设,因此引擎也不关心在运行时的变量类型。这就给效率的提高提供了更多的可能性,好比可使编译和执行这两个过程并行。

加之最新增长的 JavaScript API 容许 WebAssembly 的流编译,这就使得在字节流还在下载的时候就启动编译。

FireFox 目前正在开发两个编译器系统。一个编译器先启动,对代码进行部分优化。在代码已经开始运行时,第二个编译器会在后台对代码进行全优化,当全优化过程完毕,就会将代码替换成全优化版本继续执行。

添加后续特性到 WebAssembly 标准的过程

WebAssembly 的发展是采用小步迭代的方式,边测试边开发,而不是预先设计好一切。

这就意味着有不少功能还在襁褓之中,没有通过完全思考以及实际验证。它们想要写进标准,还要经过全部的浏览器厂商的积极参与。

这些特性叫作:将来特性。这里列出几个。

直接操做 DOM

目前 WebAssembly 没有任何方法能够与 DOM 直接交互。就是说你还不能经过好比 element.innerHTML 的方法来更新节点。

想要操做 DOM,必需要经过 JS。那么你就要在 WebAssembly 中调用 JavaScript 函数(WebAssembly 模块中,既能够引入 WebAssembly 函数,也能够引入 JavaScript 函数)。

无论怎么样,都要经过 JS 来实现,这比直接访问 DOM 要慢得多,因此这是将来必定要解决的一个问题。

共享内存的并发性

提高代码执行速度的一个方法是使代码并行运行,不过有时也会拔苗助长,由于不一样的线程在同步的时候可能会花费更多的时间。

这时若是可以使不一样的线程共享内存,那就能下降这种开销。实现这一功能 WebAssembly 将会使用 JavaScript 中的 SharedArrayBuffer,而这一功能的实现将会提升程序执行的效率。

SIMD(单指令,多数据)

若是你以前了解过 WebAssembly 相关的内容,你可能会据说过 SIMD,全称是:Single Instruction, Multiple Data(单指令,多数据),这是并行化的另外一种方法。

SIMD 在处理存放大量数据的数据结构有其独特的优点。好比存放了不少不一样数据的 vector(容器),就能够用同一个指令同时对容器的不一样部分作处理。这种方法会大幅提升复杂计算的效率,好比游戏或者 VR。

这对于普通 web 应用开发者不是很重要,可是对于多媒体、游戏开发者很是关键。

异常处理

许多语言都仿照 C++ 式的异常处理,可是 WebAssembly 并无包含异常处理。

若是你用 Emscripten 编译代码,就知道它会模拟异常处理,可是这一过程很是之慢,慢到你都想用 “DISABLE_EXCEPTION_CATCHING” 标记把异常处理关掉。

若是异常处理加入到了 WebAssembly,那就不用采用模拟的方式了。而异常处理对于开发者来说又特别重要,因此这也是将来的一大功能点。

其余改进——使开发者开发起来更简单

一些将来特性不是针对性能的,而是使开发者开发 WebAssembly 更方便。

  • 一流的开发者工具。目前在浏览器中调试 WebAssembly 就像调试汇编同样,不多的开发者能够手动地把本身的源代码和汇编代码对应起来。咱们在致力于开发出更加适合开发者调试源代码的工具。

  • 垃圾回收。若是你能提早肯定变量类型,那就能够把你的代码变成 WebAssembly,例如 TypeScript 代码就能够编译成 WebAssembly。可是如今的问题是 WebAssembly 没办法处理垃圾回收的问题,WebAssembly 中的内存操做都是手动的。因此 WebAssembly 会考虑提供方便的 GC 功能,以方便开发者使用。

  • ES6 模块集成。目前浏览器在逐渐支持用 script 标记来加载 JavaScript 模块。一旦这一功能被完美执行,那么像 <script src=url type="module"> 这样的标记就能够运行了,这里的 url 能够换成 WebAssembly 模块。

总结

WebAssembly 执行起来更快,随着浏览器逐步支持了 WebAssembly 的各类特性,WebAssembly 将会变得更快。


我最近正在写一本《React.js 小书》,对 React.js 感兴趣的童鞋,欢迎指点

相关文章
相关标签/搜索