WebAssembly 为何能改变软件的分发?WebAssembly的优势

大雄 1385 2022-09-22

如果你有90年代使用Windows和Internet Explorer的经验,那么很可能还记得ActiveX控件。大多数时候会在页面上弹出很大的窗口,提示你接下来显示的内容远不止几段文字。

还记得Java applet吗?于1995年推出,后来不仅限于Windows和Internet Explorer。我记得最近一次不得不在macOS上使用Java applet是2013年,按年代来看,2013年比90年代更接近当前。(但画面依然感觉很古老!)

似乎ActiveX和Java applet更多地在企业环境中使用,而Macromedia Flash(后来称为Adobe Flash)无疑更为消费者所熟知。早期的流视频都需要Flash(甚至那时的YouTube都需要Flash才能正常工作!),而且Flash也是2000年代末以及2010年代初浏览器游戏的主要技术。每当浏览器窗口呈现如下状况时,我们大多可以从Flash身上找原因:

似乎ActiveX未能获得广泛采用,后来微软又尝试了Silverlight:

同时,Google也在Chrome上开发了自家的产品:

坦白说,这些尝试都未能获得广泛采用,尤其是在消费者和企业都开始转向移动设备之后。根据维基百科,这些尝试最后的结局分别如下。

ActiveX:

2015年,微软发布了MicrosoftEdge,取代使用多年的Internet Explorer成为Windows的默认浏览器,但它不支持ActiveX,这标志着该技术在Web浏览器开发中的终结。

Javaapplet:

从2013年开始,主流浏览器开始逐步淘汰对底层applet的支持,截止到2015-2017年,applets已完全无法运行。自2017年Java 9以来,JavaApplet全面淘汰,并于2018年9月发布的Java SE 11(18.9)中删除。

AdobeFlash:

2017年7月,Adobe宣布Flash将于2020年底终止使用,而且Flash Player的支持、分发和安全更新也将停止。

微软Silverlight:

目前没有适用于Microsoft Edge的Silverlight插件。自2015年9月以来,GoogleChrome不再支持Silverlight插件,2017年3月Firefox也放弃了支持。

Google Native Client

2016年10月12日,一则Chromium问题票的评论表明,Google的Pepper和NativeClient团队已经人手不足。

但是JavaScript不是解决了所有问题吗?

这些浏览器的附加组件大多数是在现代JavaScript和HTML5出现之前引入的,因此有人会说,现在你不再需要浏览器附加组件。还有一些人甚至说,当初浏览器就不应该支持JavaScript或任何脚本。尽管如此,使用浏览器脚本的例子比比皆是,我们很难避免在浏览器应用程序中使用脚本。纵观浏览器插件的历史记录,一般我们都会看到以下几个方面主题:

  • 在许多情况下,通过浏览器分发应用都非常方便。

  • 对于很多游戏来说,浏览器必不可少,尤其是休闲类的游戏。

  • 在这两种情况下,浏览器都必须显示比文本和一些静态图像更复杂的内容。

图:现代塔防类休闲小游戏可以说是随着Adobe Flash和浏览器游戏的普及而复兴,其中Flash Element TD就是一个典型的例子。

尽管客观地说,原生应用对用户更好,但在应用商店出现之前,早期的浏览器应用都在尝试自己的应用商店。你无需购买CD,即可在磁盘上安装和管理应用程序。你无需手动安装更新并迁移数据。无需卸载应用,只需关闭相应的浏览器选项卡就可以了。

当浏览器脚本的功能发展到一定程度之后,一些人禁不住诱惑,他们推出了只可在浏览器上运行的应用。浏览器是跨平台的,不是吗?只需将JavaScript应用代码包装在类似浏览器的容器中(例如Electron),然后分发出去就可以了。

然而,最终不仅JavaScript API变得越来越复杂,语言本身也无法满足开发人员的需求。并非每个人都喜欢JavaScript语法(还记得CoffeeScript吗?)或语义(我不禁注意到最近几年TypeScript变得越来越流行)。但是,很难将任意编程语言转换为JavaScript,因为JavaScript的构建初衷并不在于此。

结果,JavaScript解释器本身需要内存和性能开销。而内置垃圾收集器增加了不同内存模型的语言转换为JavaScript的难度。虽然我们仍然梦想通过一种语言为所有平台编写所有应用程序,但是为什么必须选择JavaScript呢?

WebAssembly的起源

随着浏览器插件的消亡,至少浏览器供应商之间开始互通有无了。最起码所有浏览器都支持JavaScript,对于供应商来说这显然是一个好消息。随着JavaScript的需求不断增加,2013年有人开始尝试使用asm.js支持底层编程:

由于具有百分百的类型一致性,且几乎没有垃圾回收(内存管理在一个巨大的类型数组中手动进行),因此asm.js的性能超过了普通JavaScript。

从语法上看,这仍然很像JavaScript,但是当有很多底层代码时,生成的文件很快就会变得很大,并且当用户频繁-代码时,代码的大小非常重要。由于通常你不会手动编写asm.js代码,并且它主要是作为编译目标,因此有必要发明一种二进制的格式。这基本上就是WebAssembly的起源:

WebAssembly于2015年首次发布,而且首次演示是在Firefox、Google Chrome和Microsoft Edge中运行Unity的《愤怒的机器人》。这项技术继承了Mozilla和Google Native Client的asm.js,最初的实现是基于asm.js的功能集。


WebAssembly的优势

如今,你不再局限于将JavaScript作为浏览器应用程序的目标语言。在LLVM成为WebAssembly的后端之后,所有建立在LLVM之上的编译器(C、C ++、Rust、Swift等)就都可以采用它,而且无需从头重新编写所有内容。自此大量已有的软件都可以向浏览器环境靠拢了,而且如果优化得当,其运行速度基本接近原生应用。

你不仅可以在浏览器选项卡中运行有趣的小项目,例如Sandspiel和orb.farm,而且还可以运行复杂的游戏,例如Doom 3(至少可以运行演示版本)。Unity和Unreal Engine都宣布了对WebAssembly的支持,虽然我们可能看不到AAA游戏在其最初发布之日就在浏览器中运行,但这仍然表明了该平台的成熟。

图:根据其创建者所说,orb.farm是“一个虚拟的生态系统,不同种类的生物可以作为食物链中独立的一部分生存、成长和死亡”。

显然,不仅限于游戏,我们甚至可以看到苹果将iWork的C++和Objective-C代码编译成了Wasm,还有1Password也利用浏览器扩展程序大大提高了性能:

随着我们转向WebAssembly,页面的加载和分析的运行速度至少是以前的两倍,而拥有大量字段的网站在Chrome中的运行速度加快了13倍,在Firefox中的运行速度加快了39倍!

Wasm是通用虚拟机

与JavaScript相比,WebAssembly不仅可以提高性能,还可以在浏览器中运行任意代码,它是目前使用最广泛的安全沙盒环境之一。作为通用虚拟机,Wasm不仅限于浏览器。Cloudflare将其用于CDN上的边缘计算:

WebAssembly开创了很多可能性,我们为此感到十分兴奋。我们可以将其集成到Cloudflare Spectrum,利用现有的C/C++服务器代码在边缘上处理TCP和UDP协议,就像一种大规模分布的inetd。在Cloudflare上运行的游戏服务器可以减少等待时间,并尽可能靠近玩家。此外,我们还可以借助某些GPU和OpenGL绑定,直接从边缘进行3D渲染和实时流传输。

随着人们意识到Wasm技术栈的广泛适用性,WASI(WebAssembly System Interface,WebAssembly系统界面)问世了。WebAssembly本身就是“裸机”平台,它不提供任何原语,例如内存分配或文件系统访问等,这些皆由WASI提供。Docker的创建者Solomon Hykes表示:

如果WASM + WASI早在2008年就问世了,那么我们就不需要Docker。这充分说明了其重要性。服务器上的Webassembly是计算的未来。我们缺少的只是标准的系统接口。希望WASI能够胜任这项工作!

很多人可能都知道iOS应用商店禁止发布编译器或虚拟机。但是你可以使用Wasm,在任何新iOS设备上安装JIT编译器和虚拟机。人们能够在已通过应用商店批准的应用内添加C++编译器和命令行Shell,因此,我们希望这能够成为在iOS上分发开发人员工具的合法方式。


图:iOS应用商店中的a-Shell和Textastic。

最近让我非常震惊的是一款JIT编译器,用于在浏览器中运行的x86二进制代码(虽然还不能在所有浏览器中运行,其中涉及一些当前仅在Chrome中支持的功能):

作为CheerpX的一部分,我们实现了一个快速的x86解释器和JIT编译器,可以即时生成WebAssembly模块,完全在客户端有效地执行任意x86应用程序和库。

WebAssembly作为平台

作为安全快速的沙盒,Wasm似乎非常适合编写应用程序插件。我们可以想象,VSCode或Atom之类的编辑器不仅可以编写JavaScript文件,而且还可以使用任何语言编写WebAssembly。这可以丰富他们的扩展生态系统,并进一步提高该平台的性能。Mono和Xamarin的创造者Miguel de Icaza对此表示赞同,并表示:

IDE/编辑器/工具可以在开发阶段利用WebAssembly来承载自己喜欢的语言编写的脚本,而对于产品的最终版本(如Unity、Godot、Rhino3D、Unreal Engine以及其他提供脚本功能的应用程序),他们可以捆绑到原生代码,而不必依赖WebAssembly。

与Java / JVM相比,WebAssembly可以更直接地实现“编写一次,随处运行”的理想目标。这要归功于整个栈的开放性,开发人员的无私奉献(跨越各种语言和生态系统)以及苹果、Google、Mozilla和微软等浏览器供应商的直接参与。而90年代和00年代破碎的生态系统则截然相反,为了保护自家的产品,每个供应商都有自己的特殊插件,并强迫开发人员使用特定的编程语言。

WebAssembly还需要什么

与任何早期的技术栈一样,WebAssembly领域还远远不够完善。例如,通过print语句调试Wasm非常麻烦,并非浏览器都提供多线程支持,而且还未正式进入实现阶段。缺乏稳定的动态链接ABI还不算太致命,毕竟静态链接可以降低某些工作的难度,但有时候仍然会引起麻烦。

绝大多数消费者计算设备(根据http://caniuse.com,截至2020年9月,这一数字为92%)都有通用的虚拟机,几乎所有编程语言都可以将其作为目标,这一点让我非常动心。WebAssembly需要更多开发人员的关注,如果一切顺利,我相信在接下来在几年内我们将看到更多前所未有的产品。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:FinClip为程序员准备丰厚福利,程序员你只管努力打工
下一篇:小程序平台布局,用体面的方式构建小程序生态
相关文章

 发表评论

暂时没有评论,来抢沙发吧~