WebAssembly如何改变软件分发

2020-09-09 22:54:26

如果您在90年代有过使用Windows和Internet Explorer的经验,很可能您还记得ActiveX控件。大多数情况下,这涉及到页面上的大型弹出窗口,这些控件必须显示比几个文本块更复杂的内容。

或者,还记得Java applet吗?它们在1995年面世,后来并不局限于Windows和Internet Explorer。我记得,直到2013年,我还不得不在MacOS上使用Java小程序,从时间上讲,它比90年代更接近现在的时间。(反正感觉好老!👴)。

似乎ActiveX和Java applet是企业世界的必需品,但Macromedia Flash(后来称为Adobe Flash)肯定更广为人知。这在流媒体视频的早期是一项要求(当时甚至YouTube也需要Flash才能工作!),但在2000年代末和2010年代初,这也是浏览器游戏的主要推动力。我们当然可以指责Flash让我们的浏览器窗口看起来是这样的:

虽然ActiveX似乎没有得到很大的采用,但微软对Silverlight进行了另一次尝试:

公平地说,这些尝试没有建立起广泛的采用,特别是在消费者和企业都开始转向移动之后。据维基百科报道,所有这些尝试是如何结束的:

微软在Windows 8中从Internet Explorer 10的Windows应用商店版本中取消了对ActiveX的支持。2015年,微软发布了Microsoft Edge,这是Internet Explorer的替代品,不支持ActiveX,这标志着微软网络浏览器开发技术的终结。

从2013年开始,主要的网络浏览器开始逐步取消对用于运行的底层技术的支持,到2015-2017年间,小程序变得完全无法运行。Java小程序自2017年Java 9起不再推荐使用,并从2018年9月发布的Java SE 11(18.9)中删除。

2017年7月,Adobe宣布Flash将于2020年底停产,并将停止对Flash Player的支持、分发和安全更新。

没有适用于Microsoft Edge的Silverlight插件。自2015年9月以来,Googlechrome或自2017年3月以来,火狐都没有对其提供支持。

2016年10月12日,一条关于Chromium问题跟踪器的评论指出,谷歌的Pepper和Native Client团队已经松懈。

这些浏览器插件中的大多数都是在现代JavaScript和HTML5问世之前推出的,因此有人可能会争辩说,您根本不再需要浏览器插件了。嗯,有些用户甚至说浏览器从一开始就不应该支持JavaScript或任何脚本。尽管如此,浏览器脚本和浏览器应用程序还是有足够的用例是很难避免的。当回顾浏览器插件的历史时,很难不注意到以下几个主题:

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

尽管原生应用客观上对用户更有利(在许多情况下仍然如此),但早期的浏览器应用在App Store存在之前就尝试建立自己的临时应用商店。您不必随应用购买CD并将其安装和管理在磁盘上。您不必手动安装更新和迁移数据。不需要卸载应用程序,您只需关闭相应的浏览器选项卡,然后将其忘掉即可。

当浏览器脚本功能变得足够高级时,一些人开始看到让他们的应用程序的浏览器版本成为他们提供的唯一版本的吸引力。浏览器是跨平台的,不是吗?只需将您JavaScript应用程序代码包装在一个类似浏览器的容器(比如Electron)中,然后分发该代码,而不是分发您的本机应用程序。

但最终不仅JavaScriptAPI变得更加复杂,语言本身也不能再适应开发人员的需求。并非每个人都喜欢JavaScript语法(还记得CoffeeScript吗?)。或者语义学(我情不自禁地注意到,打字本近年来越来越受欢迎)。但是很难将任意的编程语言转换成JavaScript,后者在构建时并没有考虑到这一目标。

由此推论,JavaScript解释器本身既有内存开销,又有性能开销。内置大容量收集器使得将具有不同内存模型的语言转换为JavaScript变得更加困难。只有一种语言来编写适用于所有平台的所有应用程序的吸引力仍然存在,但是为什么您必须局限于JavaScript本身,即使是作为目标语言呢?

随着浏览器插件的消亡,至少我们可以赞扬浏览器服务商的互操作性努力。所有浏览器都支持JavaScript的一些最低公分母,供应商有明确的动机跟上。随着需求超越JavaScript,2013年开始尝试使用asm.js支持低级编程:

与普通JavaScript(使用asm.js)相比,这种性能提升很大程度上是由于100%的类型一致性,而且几乎没有垃圾回收(内存是在大型类型化数组中手动管理的)。

从语法上看,这看起来仍然很像JavaScript,但是当您有很多低级代码时,生成的文件可能会很快变大,并且当您的用户频繁下载代码时,代码的大小非常重要。因为在大多数情况下不应该手动编写asm.js代码,并且它主要是作为编译目标设计的,所以为它发明一个二进制格式是有意义的。WebAssembly基本上就是这样开始的:

WebAssembly于2015年首次发布,第一次演示是在Firefox、Google Chrome和Microsoft Edge上执行Unity的AngryBots。前身技术是来自Mozilla和Google Native client的asm.js,最初的实现基于asm.js的特性集。

现在,您不再局限于将JavaScript作为浏览器应用程序的目标语言。一旦LLVM或多或少地准备好了WebAssembly后端,它就允许构建在LLVM(用于C、C++、Rust、Swift等)之上的编译器采用它,而无需从头开始重写所有内容。这将浏览器环境释放给大量预先存在的软件,如果优化得当,这些软件也可以接近本机速度运行。

您不仅可以在浏览器选项卡中运行诸如SandSpiel和orb.arm这样有趣的小项目,还可以使用诸如Doom3(至少是其演示版本)这样的复杂游戏。Unity和UnrealEngine都宣布支持WebAssembly,虽然我们在最初的发布日期可能不会看到AAA游戏在浏览器中运行,但这仍然给了我们对平台成熟度的足够信心。

这显然不仅仅局限于游戏,因为我们可以看到苹果员工将他们的C++和Objective-CCODE从iWork编译到Wasm 1,或者1Password在他们的浏览器扩展中使用它,从而获得了实质性的性能改进:

随着我们转向WebAssembly,页面填充和分析现在的运行速度至少是以前的两倍,那些有大量字段的网站在Chrome中快了13倍,在Firefox中快了39倍!它燃烧得很快。🔥

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

WebAssembly带来的各种可能性让我们兴奋不已。也许,通过与Cloudflare Spectrum集成,我们可以允许现有的C/C++服务器代码在边缘处理任意的TCP和UDP协议,就像一种大规模分布的inetd。也许游戏服务器可以通过在Cloudflare上运行,尽可能靠近玩家来减少延迟。也许,在一些GPU和OpenGL绑定的帮助下,您可以直接从边缘进行3D渲染和实时流媒体。

随着人们认识到WASM技术栈的广泛适用性,WASI(WebAssembly System Interface)的出现也就不足为奇了。在WebAssembly本身是一个“裸机”平台的情况下,它不提供任何原语,比如内存分配或文件系统访问,而WASI确实提供了这些原语。正如Docker,Putsit的创始人所罗门·海克斯(Solomon Hykes)所说:

如果WASM+WASI在2008年就存在了,我们就不需要创建Docker了。这就是它有多重要。服务器上的WebAssembly是计算的未来。标准化的系统接口是主题化的环节。希望瓦西能胜任这项任务!

你们中的许多人可能知道,通过iOS AppStore运送编译器或虚拟机是被禁止的。使用Wasm,您可以在任何较新的iOS设备上安装终极JIT编译器和虚拟机。不足为奇的是,人们已经能够在App Store批准的应用程序中发布C++编译器和命令行外壳,所以让我们希望这仍然是在iOS.🤞上分发开发人员工具的合法方式。

最近让我大吃一惊的是针对在浏览器中运行的x86二进制代码的JIT编译器(目前还不是所有的浏览器,它需要一些目前只在Chrome中支持的功能):

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

作为一个安全快速的沙箱,Wasm似乎也很适合应用程序插件。可以想象VSCode或Atom这样的编辑器不仅允许用JavaScript编写扩展,还允许用任何可以针对WebAssembly的语言编写扩展,这将使它们的扩展生态系统更加丰富,并释放出该平台提供的性能改进。Mono和Xamarin的创始人米格尔·德·伊卡扎(Miguel De Icaza)对此表示赞同,并进一步提出了这个想法:

[…]。IDE/编辑器/工具可以利用WebAssembly在开发阶段托管他们最喜欢的脚本语言,但对于产品的最终构建(如Unity、Godot、Rhino3D、虚幻引擎和任何其他提供脚本功能的应用程序),他们可以捆绑本地代码,而不必依赖于WebAssembly。

WebAssembly可以说是实现“一次编写,随处运行”这一理想目标的一条比Java/JVM更直接的途径。这要归功于整个堆栈的开放性、潜在开发者的思想共享(跨越大量不同的语言和生态系统),以及苹果、谷歌、Mozilla和微软等浏览器供应商的直接参与。这与我们在90年代和00年代看到的支离破碎的生态系统截然相反,当时每个供应商都有自己的特殊插件,迫使你使用特定的编程语言作为把关措施。

与早年的任何技术堆栈一样,在WebAssembly领域,并不是所有东西都是完美无缺的。如果我没有提到使用print语句进行调试仍然是Wasm的目标,或者多线程支持在所有浏览器中都不可用并且正式还没有达到实现阶段,这将是不公平的。缺乏稳定的ABI用于动态链接并不重要,静态链接使某些事情变得更容易,但它有时仍然会产生影响。

事实上,绝大多数消费者计算设备(根据caniuse.com的数据,截至2020年9月,92%)都有一个几乎可以被任何编程语言访问的通用虚拟机,这一事实仍然让我着迷。WebAssembly无疑需要开发人员更多的关注,如果一切顺利,几年后我们将看到更多以前不可能实现的产品。

WASM是一个缩写,但不是首字母缩写,它是WebAssembly规范作者使用的大写形式(除了全小写的“wasm”之外)。因此,我们应该跟随作者的脚步,使用这个大写变体,除非您是其中之一,编写“iOS”、“XCode”或“iPhone”。🙈。

↩。

如果你喜欢这篇文章,请考虑成为赞助商。我的目标是制作这样的内容,并全职从事开源项目,每一篇贡献都让我离它更近了!作为我的开源项目的读者和用户,这也会给您带来好处,确保我的博客和项目不断得到维护和改进。