WebAssembly 是一个新兴标准,其目标是定义一个安全、可移植、大小和加载时间高效的二进制编译器目标,提供接近原生性能——Web 的虚拟 CPU。 WebAssembly 正在 W3C 社区组 (CG) 中开发,其 成员 包括 Mozilla、Microsoft、Google 和 Apple。
我很高兴地宣布,WebAssembly 已经取得了一个重要的里程碑:**现在有 多个、互操作的、实验性的浏览器实现**。在发布之前,我们还有很多工作要完成标准的实现,但这是一个很好的机会来展示我们迄今为止的进展,谈谈接下来会发生什么,并征求反馈。
为什么选择 WebAssembly?
JavaScript 的低级 asm.js 子集不仅证明了浏览器可以实现安全、沙盒、接近原生的计算性能,而且证明了 Web 上对此类功能的巨大需求。 借助 Emscripten 编译器,我们已经看到 asm.js 被用于各种各样的应用程序,包括地图、加密、压缩、游戏、CAD、图像编辑和人脸识别。
WebAssembly CG 去年 成立,旨在将 Web 推向更远一步,使用一个标准化的二进制格式,其存储大小和解码时间可以优化到超出 JavaScript 可能达到的水平。 此外,作为一项新标准,WebAssembly 能够独立于 JavaScript 的演变来演变,以适应低级功能。
同时,我们知道 WebAssembly 必须“属于 Web”:它必须访问现有的 Web API 并与 JavaScript 密切集成,例如,允许在 WebAssembly 和 JavaScript 之间进行调用。 与传统的插件模型不同,这将使 WebAssembly 更容易集成到 JavaScript 应用程序和库中,就像 asm.js 一样。
最后,我们能够借鉴我们在 Emscripten 和 asm.js 上的多年1,2,3,4,5,6,7 的经验来指导和集中 WebAssembly 的初始设计。 至关重要的是,在现代浏览器上,asm.js 代码的性能非常好,创建 polyfill 将允许开发人员开始使用 WebAssembly,即使在浏览器市场上原生实现尚未达到饱和状态之前。
进展
快进到今天,CG 已经取得了非凡的进展。 在 WebAssembly GitHub 组织 中,该组已经产生了
更重要的是,四个浏览器引擎的工程师已经实现了原型 WebAssembly 实现1,2,3,4。 在 Firefox 中,我们重构了现有的 asm.js 优化管道,以使用 WebAssembly 的二进制格式作为从主解析线程发送到后台编译线程的 asm.js 代码的表示形式。
这种改变最终通过将两个代价高昂的步骤(MIR 和代码生成)从顺序关键路径中移除,从而显著提高了 asm.js 并行编译性能。 使用此重构的管道,原生 WebAssembly 解码只需要添加一个小的新前端来验证不可信的字节
有关这些术语的定义以及有关 JS 和 asm.js 编译的更多背景信息,请参阅 这篇 之前的博客文章。
实验 WebAssembly
有了所有这些要素,现在就可以构建在多个实验性实现上运行的 WebAssembly 演示。 我们确实是说“实验性的”:WebAssembly 的二进制格式和 JS 绑定可能会在未来几个月发生不兼容的更改,直到第一个版本稳定为止。 我们预计实现还需要一段时间才能成熟到足以进行压力测试或基准测试。 相反,此里程碑的重要性在于让所有浏览器都在同一页面上,这样我们才能继续同步迭代。
尽管如此,我们还是很高兴看到一个 真正起作用的演示,它可以在多个浏览器中运行
这个特定的演示实际上具有一些怀旧价值:AngryBots 是一个 Unity 教程项目,在启动 Unity 的 WebGL 导出时用作冒烟测试。 美好的回忆!:)
要运行演示,请下载一个 Nightly 版本,打开 about:config
并将 javascript.options.wasm
设置为 true
。
发布路径
那么接下来是什么?在我们拥有一个稳定的、可发布的第一个版本之前,还有很多工作要做。 在 CG 中,一些重要的剩余任务是
- 定义 官方 WebAssembly 文本格式。
- 进一步减小二进制格式大小。 虽然当前的二进制格式比 asm.js 压缩前小 42%(gzip 后小 12%),但我们从 之前的原型二进制格式工作 中得知,可以进一步显著减小大小。
- 迭代 WebAssembly JavaScript API。 目前,实验性版本定义了一个新的同步函数
Wasm.instantiateModule
,它同时进行编译和实例化。 有初步计划将这些步骤分开,并提供同步和异步函数,这些函数会生成一个 结构化可克隆的 代码对象。 这使开发人员比当前 Firefox 中 asm.js 的隐式机器码缓存 对编译和机器码缓存有更多控制权。 - 为编译器编写者、工具作者、黑客和学生创建更易于理解的文档。
- 在测试套件中添加更多测试。
在 Firefox 中,我们还计划
- 在浏览器开发者工具中添加 WebAssembly 支持,包括调试器和分析器。 幸运的是,JavaScript、开发者工具和 Firebug 团队共同努力将工具迁移到一个新的、抽象的、可进行单元测试的 调试器 API,我们将为 WebAssembly 代码实现该 API。 事实上,这项工作已经 开始,这就是为什么如果你为上面的演示打开调试器选项卡,你已经可以看到为二进制代码生成的占位符文本格式(当然,它会在官方文本格式准备好后切换到官方文本格式)。
- 进一步缩短冷启动时间。 在 16×2.4Ghz 内核的 Linux 台式机上测量 AngryBots 的编译时间,WebAssembly 将编译时间缩短了大约 52%。 这是一个良好的开端,并且利用了 WebAssembly 解码目前比 asm.js 解析快约 10 倍的事实,但通过处理编译管道的其他部分,可以显著进一步缩短冷启动时间。
- 完成添加完整集的 WebAssembly 运算符并导入测试套件。
全速前进
迄今为止,WebAssembly 的进展令人振奋。 我继续对整个 WebAssembly 社区组的协作氛围印象深刻并表示感谢。 如果你想了解更多信息,GitHub 组织页面 是一个很好的起点。 祝您编程愉快!
关于 Luke Wagner
Luke Wagner 是 Mozilla 的软件工程师,在 Firefox 中从事 JavaScript 和 WebAssembly 的工作。
14 条评论