WebAssembly2021年回顾和2022年展望

本文最初发表于Uno平台博客。
和去年一样(去年作者写了2020年WebAssembly的发展以及对2021年的预测),本文将首先回顾过去一年WebAssembly的发展,然后预测其明年的趋势。
回顾2021
过去一年来WebAssembly的发展比我之前的预测要快得多,SafariWeb浏览器在这方面表现得尤为出色。
Safari浏览器
当WebAssembly2017年刚刚发布MVP版本时,Safari还与其他浏览器处于同一水平。经过多年的发展,Safari不幸地落在了后面。
进入2021年,我很高兴看到Safari继续发布更新以支持WebAssembly。这或许是Safari追赶其他厂商的开始。随着Safari15.2于2021年12月14日发布,Safari2021年全年更新发布了以下功能:
流编译
大内存操作
可寻址内存高达4GB
支持COOP和COEP响应标头
原子指令
重新启用对使用COOP/COEP响应标头的网站的共享缓存的支持
共享缓存
借助共享缓冲区,WebAssembly可以在多个线程之间共享内存。不幸的是,由于共享缓存目前存在Spectre和Meltdown安全漏洞,因此共享缓存被禁用,直到人们找到合适的漏洞解决方案。
Chrome桌面应用程序是第一个通过采用站点隔离作为该漏洞的解决方法来重新启用共享缓存的应用程序。从现在开始,在响应标头中添加COOP或COEP意味着告诉浏览器需要创建一个隔离环境,以便安全地重新启用共享缓存。
Firefox桌面应用程序通过将这些响应标头添加到响应标头中,在2020年首次重新启用共享缓存。到2021年初,Chrome桌面应用将对共享缓存的支持更新为最新标准。从现在开始,如果您想使用共享缓存功能,则必须添加这些响应标头。
同时,Chrome的Android端也在2021年初宣布支持这些响应头,使得在移动端使用WebAssembly的多线程成为可能。随着最新版本的Safari重新开放对共享缓存的支持,除了Firefox移动版之外的所有现代浏览器都支持WebAssembly的多线程。
我原本预计Firefox移动版会在2021年支持这些响应标头,但不幸的是它没有发生。不过,Firefox移动端很有可能在2022年完成对这些响应头的支持。
固定宽度SIMD
SIMD同时将相同的指令应用于多个数据节点。这样,计算性能就可以得到很大的提升。例如,通过利用CPU的SIMD指令,可以大大提高图像处理能力。
SIMD有多种类型,首先,WebAssembly决定支持128位固定宽度SIMD操作。
Chrome和Firefox分别于2021年5月和6月增加了对固定宽度SIMD的支持,但Safari尚不支持。
到目前为止,WebAssembly还没有内置的异常处理模块。为了填补这一空白,应用程序必须使用JavaScript添加额外的异常处理代码。然而,当这些异常处理逻辑代码内置到模块中时,不仅会增加模块的大小,而且会影响性??能。因此,除非必要,一般建议不要在模块中使用异常处理。
Chrome于9月份正式发布了异常处理功能。然而令我惊讶的是,Safari在12月份也实现了异常处理功能,并决定在15.2版本中正式发布。
目前Firefox和Node.js尚不支持,他们仍在努力开发中。
根据Chrome和Node.js的JavaScript引擎V8的发行说明,与使用JavaScript的异常处理相比,使用WebAssembly的异常处理可将代码大小减少43%,与不使用任何异常处理相比,代码大小会增加9%。同时,WebAssembly的异常处理对性能没有影响,而JavaScript的异常处理会对性能产生30%的负面影响。
如果你对V8版本中WebAssembly异常处理的细节感兴趣,可以查看V8版本发行说明:
https://v8.dev/blog/v8-release-95#webassembly。
模块链接和接口类型
模块链接提案是关于在两个或多个模块定义之间建立链接并让WebAssembly运行时在运行时为您处理此链接的过程。
接口类型提案描述了模块如何通过高级数据类型定义相互通信。例如,一个模块可能使用UTF-8字符串,而另一模块可能使用UTF-16字符串。通过描述它们的数据类型,WebAssembly运行时将使模块之间的通信变得更容易。
我本来预计这两项提案会在2021年完成,看来虽然取得了一些初步成果,但未来还需要继续努力。
.NET6
在过去的一年里,.NET做了很多努力,无论是在工具还是性能方面,都进一步完善了对WebAssembly的支持。11月6日版本发布的AOT编译功能就是其中之一。
通常,.NET代码的编译分为两个步骤。首先将本地代码编译成IL(.NET架构中的中间语言),然后通过目标机的即时编译在部署的目标机上完成剩余的编译。这个过程其实有点类似于WebAssembly的工作机制。
当这种编译机制的代码在客户端浏览器中运行时,WebAssembly代码就是.NETWebAssembly运行时本身,而应用程序代码都是IL文件。这种按需编译执行IL文件的方法在性能上与直接执行编译后的文件无法相比。
在AOT编译模式下,应用程序的所有.NET代码都将被编译为WebAssembly。虽然这种方法会增加文件大小,但可以获得更好的性能。然而,大文件会导致应用程序的首次加载时间较长。
考虑到IL和AOT两种不同编译方法的优缺点,使用面向配置的AOT编译可能是最好的选择。这样,我们就可以通过AOT来编译经常使用的代码,而其余部分则使用IL编译。
除此之外,我们的Uno平台还引入了一项称为XAML资源修剪的功能。它可以与AOT编译一起使用,以删除那些未使用的代码。在测试中,人们发现这种方法可以将WebAssembly应用程序的代码减少50%。
字节码联盟
字节码联盟最初是由Intel、Mozilla、RedHat和Fastly组成的组织。其目标是构建一个安全平台,通过利用WebAssembly和WASI等标准,可以在任何平台、设备或操作系统上运行不受信任的代码。。
WASI(WebAssembly系统接口)是关于如何在浏览器之外安全一致地使用WebAssembly的标准。如果你想了解更多相关知识,LinClark写了一篇很好的文章解释WASI:WASI-WebAssembly系统接口标准:
https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/。
从一开始,联盟就希望有更多的组织加入。为此,组织的内部结构必须进行相应的调整,以适应组织未来的发展壮大。当基金会创建时,红帽退出,微软加入,帮助其他创始人将该组织合并为非营利组织。2021年,该联盟扩大规模,目前包括Microsoft、Google、Arm、DFINITY基金会、PrepStudio、Shopify和加州大学圣地亚哥分校。
该联盟除了支持WASI外,也是Wasmtime、cranlift、Lucet、WAMR和Enarx等项目的来源。如果您对字节码联盟感兴趣,可以通过此链接获取更多信息:
https://bytecodealliance.org/。
WebAssembly应用领域
每年我们都会看到越来越多的商业产品添加对WebAssembly的支持。例如,2020年,Zoom、GoogleMeet、GoogleEarth、Firefox浏览器都加入了CloudflareWorkers等基于WebAssembly的无服务器计算产品的竞争。此外,还有eBay的条码扫描仪、AutoCAD的网络应用程序和Unity游戏引擎。
2021年也不例外,这里有一些使用WebAssem的方法bly的新区域:
迪士尼应用程序开发套件使用WebAssembly
网页上发布了Photoshop的简化版
微软模拟飞行有一个基于WebAssembly的插件系统
随着功能和工具的改进,以及越来越多的商业产品使用WebAssembly,我们开始看到WebAssembly在框架和通用Web中使用。尽管应用领域和产品仍然较少,但其持续增长令人兴奋。
2021年对于WebAssembly来说是伟大的一年,那么2022年我们可以期待什么呢?
2022年预测
我认为2022年肯定会发生的是WebAssembly在几乎每个领域的功能的进一步增强和改进。我最期待的是异常处理。
异常处理
异常处理是许多编程语言的主要功能,因此它位于待办事项列表的首位。Safari、Chrome和Edge已经具备此功能,Firefox和Node.js也在积极开发中。
由于低性能的JavaScript版本仍然可以使用,因此当您需要在模块中使用异常处理时,如果可以使用性能更好的WebAssembly异常处理,则升级以使用它,否则回退到使用JavaScript异常处理。的版本.
共享缓存
如前所述,几乎所有现代桌面和移动浏览器现在都支持COOP/COEP响应标头,包括Firefox桌面版。这些响应标头允许浏览器安全地启用共享缓存,从而允许您的模块使用WebAssembly多线程。
在现代浏览器中,只有Firefox移动版不支持这些响应标头。不过,Firefox移动版计划在2022年2月发布的97版本中支持这些响应标头。
固定宽度SIMD
我预计该功能将在今年的Safari版本中实现。
我的推理是,Safari在2021年增加了对WebAssembly的支持,WebAssembly固定宽度SIMD规范现已标准化,并且Xcode(Apple的操作系统开发环境)已经支持SIMD。
尾调用
为了支持WebAssembly,一些编程语言不得不使用尾调用。尽管许多事情都有解决方法,但过程很慢。此外,尾调用在编译优化和流程控制方面也发挥着积极的作用。该提案已经完成了一段时间,但如果想进入第四阶段,至少有2个供应商(Chrome、Firefox或Safari)必须实现此功能。Chrome已经在版本标签中实现了此功能,但它不打算在达到第4阶段之前正式发布它。因此我们仍然需要等待至少还有一个供应商来实现此功能。
并不是厂商不想实现这个功能,而是他们都在忙于他们认为更重要的事情。所以人们正在努力提高这个功能在各个厂商眼中的重要性和优先级。
支持多种记忆
该提议是使模块能够具有多个内存模块。
多存储器的一种使用场景是模块使用一个内存区域作为自己的内部数据区域,并将另一内存区域传递给一些需要写入数据的模块。通过这种方式,可以防止由于外部模块的异常写入而导致模块内部数据损坏。同时,这种方法还可以有效隔离敏感数据和共享数据,起到一定的安全作用。
另一种多内存使用场景是,在WebAssembly的多线程中,你可以让这些线程拥有一个共享内存区域,并将其他模块数据保存到另一个内存区域。
如果您对多内存区域的使用场景感兴趣,可以查看多内存的介绍(
https://github.com/WebAssembly/multi-memory/blob/main/proposals/multi-memory/Overview.md)了解更多使用场景。
该提案目前已进入第三阶段,有很多令人瞩目的应用场景。所以我特别希望它能在今年正式发布。
WASI(WebAssembly系统接口)
正如本文前面提到的,我预计模块链接和接口类型的两个提案将在2021年完成。但不幸的是,它们仍在进行中,不会像我预期的那样在2021年完成。
这些建议不仅是WebAssembly的一部分,而且是创建组件模型的基本功能。根据这个WASI帮助文档描述,该组件该模型类似于操作系统的进程模型,用于定义进程如何启动以及如何相互通信。WASI在这里的作用类似于操作系统的API层。
因此,组件模型和WASI的接口类型提案都将在2022年继续发展。如果您对WASI的提案感兴趣,可以浏览WASI提案列表(
https://github.com/WebAssembly/WASI/blob/main/docs/Proposals.md)查看更多。
总结
在过去的一年里,我们看到了WebAssembly多线程中共享缓冲区、固定宽度SIMD和异常处理等功能来提高WebAssembly性能。同时.NET6改进了对WebAssembly的支持,.NET和Uno平台都通过添加AOT进一步提高了WebAssembly的性能。
Safari在2021年是一个巨大的惊喜,他们做了很多工作来赶上其他浏览器的WebAssembly支持。
2021年,我们将看到更多的商业产品加入使用WebAssembly的行列,同时WebAssembly也开始在公共网络上使用。
由此看来,2022年肯定会是WebAssembly发展的又一个好年头,因为那些现在不支持的功能很可能会在2022年正式发布并投入生产。
WebAssembly本身有许多有趣的功能建议。同时,字节码联盟将继续协助WebAssembly在浏览器场景的实现和功能升级。
如果您对WebAssembly功能支持的发展路径感兴趣,可以通过以下网站了解更多信息。第一列显示功能列表:WebAssembly功能路线图(
https://webassembly.org/roadmap/)。
感谢特邀嘉宾GerardGallant,《WebAssemblyinAction》的作者和高级软件开发人员,撰写了另一篇关于WebAssembly当前和未来状态的综合文章。