天天看點

WebAssembly 2021 年回顧與 2022 年展望

作者 | Uno 平台團隊

譯者 | 許學文

策劃 | 闫園園

審校 | 王強

本文最初釋出于 Uno 平台的部落格。

和去年(去年作者寫了 WebAssembly 2020 年發展和 2021 年預測)一樣,本文将先回顧下 WebAssembly 過去一年的發展,然後預測下其未來一年的趨勢。

回顧 2021

過去一年 WebAssembly 的發展遠比我之前預測的要快很多,Safari web 浏覽器這方面尤為突出。

Safari 浏覽器

在 2017 年 WebAssembly 剛剛釋出 MVP 版本的時候,Safari 還和其他浏覽器一樣處在相同水準線上。然後經過多年的發展,Safari 很不幸被甩在了後面。

時間來到 2021 年,看到 Safari 不斷釋出對 WebAssembly 支援的更新,我感到興奮不已。這或許是 Safari 趕超其他廠商的開始。随着 2021 年 12 月 14 日 Safari 15.2 版本的釋出,2021 年全年 Safari 更新釋出了如下功能特性:

流編譯

大記憶體操作

可尋址記憶體達到 4GB

異常處理

支援 COOP 和 COEP 的響應頭

原子指令

對于使用了 COOP/COEP 響應頭的網站重新開啟對共享緩存區的支援

共享緩存區

借助共享緩存區,WebAssembly 可以在多線程之間實作記憶體共享。不過可惜的是,由于共享緩存區目前存在 Spectre 和 Meltdown 安全漏洞,是以在人們找到合适的漏洞解決方案之前,共享緩存區是被禁用的。

Chrome 桌面應用是第一個通過采用站點隔離作為漏洞解決方案來重新啟用共享緩存區的。至此之後,在響應頭添加 COOP 或 COEP,就意味着是告訴浏覽器需要建立一個隔離的環境,以便安全地重新啟用共享緩存區。

Firefox 桌面應用則是在 2020 年首次通過在響應頭中添加這些響應頭來重新啟用共享緩存區。到了 2021 年初的時候,Chrome 桌面應用将對共享緩存區的支援更新到了最新标準。此後,如果你想使用共享緩存區功能,就必須添加這些響應頭了。

同時,Chrome 的安卓端也在 2021 年初宣布對這些響應頭的支援,使得在移動端使用 WebAssembly 的多線程成為可能。随着 Safari 最新版本重新開啟對共享緩存區的支援後,除了 Firefox 移動端之外,所有的現代浏覽器都支援了 WebAssembly 的多線程。

我本來預計 Firefox 移動端會在 2021 年支援這些響應頭,不過可惜并沒有發生。不過在 2022 年 Firefox 移動端極有可能完成對這些響應頭的支援。

固定寬度 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 還不支援,他們還在努力開發中。

根據 V8 (Chrome 和 Node.js 的 JavaScript 引擎)的釋出說明顯示,使用 WebAssembly 的異常處理比使用 JavaScript 的異常處理代碼大小下降了 43%,與不使用任何異常處理相比代碼大小增加了 9%。與此同時,WebAssembly 的異常處理對性能無影響,而 JavaScript 的異常處理則會對性能産生 30% 的負面影響。

如果對 V8 版本中針對 WebAssembly 異常處理的詳細資訊感興趣的話,可以檢視 V8 版本釋出說明:https://v8.dev/blog/v8-release-95#webassembly。

子產品連結和接口類型

子產品連結提案是關于在兩個或多個子產品定義之間建立連結,且讓 WebAssembly 運作時在運作期間為你處理這種連結的過程。

接口類型提案描述的是子產品互相之間如何通過進階的資料類型定義實作互相之間的通信。例如,一個子產品可能使用 UTF-8 字元串,而另一個子產品可能使用 UTF-16 字元串,通過描述它們的資料類型,WebAssembly 運作時就會更加容易實作子產品間的通信。

我原先預計這兩項提案會在 2021 年完成,目前看來,雖然取得了一些階段性的成果,但未來仍然需要繼續發力。

.NET 6

過于的一年裡,為了進一步提高對 WebAssembly 的支援,不管是在工具方面還是性能方面,.NET 都做了很多努力。在 11 月份 6 版本中釋出的 AOT 編譯功能就是其中之一。

通常.NET 代碼的編譯分兩步,首先将本地代碼編譯為 IL(.NET 架構中的中間語言),然後在部署的目标機器上,通過目标機器的即時編譯完成剩下的編譯。這個過程其實和 WebAssembly 的工作機制有點類似。

當這種編譯機制的代碼運作在用戶端浏覽器的時候,WebAssembly 代碼就是.NET WebAssembly 運作時本身,而應用的代碼則全是 IL 檔案。這種按需編譯執行 IL 檔案的方式在性能上無法和直接執行已編譯檔案的方式相提并論。

在 AOT 編譯方式中,應用的.NET 代碼将全部被編譯為 WebAssembly。這種方式雖然增加了檔案的大小,但卻獲得了更好的性能,不過,大檔案會導緻應用的首次加載時間過長。

考慮到 IL 和 AOT 兩種不同編譯方式的優劣,使用配置導向的 AOT 編譯或許是最佳選擇。通過這種方式,我們可以将頻繁使用的代碼通過 AOT 進行編譯,而剩下的部分則采用 IL 的編譯方式。

除此之外,我們的 Uno 平台還引入了一個名為 XAML 資源修剪的功能。它可以與 AOT 編譯一起删除那些未使用的代碼。人們在測試中發現,通過這種方式可以使 WebAssembly 應用程式的代碼減少 50%。

位元組代碼聯盟

位元組碼聯盟最初是由英特爾、Mozilla、紅帽和 Fastly 組成的一個組織,其目标是通過利用 WebAssembly 和 WASI 等标準,建構一個可以在任何平台、裝置或作業系統上運作不可信代碼的安全平台。

WASI(WebAssembly 系統接口)是如何在浏覽器之外的場景安全且一緻的使用 WebAssembly 的标準。如果你想了解更多相關資訊,Lin Clark 寫了一篇很好的文章來解釋 WASI: WASI-WebAssembly 系統接口标準:https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/。

聯盟從一開始就希望更多的組織加入,為此組織内部的架構必須做相對應的調整,才可以滿足組織未來的發展和壯大。在建立基金會的時候,紅帽公司退出,微軟加入且幫助其他創始人将該組織合并為一個非營利性組織。2021 年,聯盟得以擴大,現在組織成員包括了微軟、谷歌、Arm、DFINITY 基金會、普萊普工作室、Shopify 和加州大學聖地亞哥分校。

除了支援 WASI,該聯盟也是 Wasmtime、cranlift、Lucet、WAMR 和 Enarx 等項目的來源。如果你對位元組碼聯盟感興趣,可以通過連結擷取更多資訊:https://bytecodealliance.org/。

WebAssembly 應用領域

每年我們都看到越來越多的商業産品增加了對 WebAssembly 的支援。例如,在 2020 年,Zoom、谷歌 Meet、谷歌 Earth 和 Firefox 浏覽器都加入了諸如 Cloudflare Workers 等基于 WebAssembly 的無服務計算産品競的争行列。除此之外,還有 eBay 的條形碼掃描器、AutoCAD 的 web 應用程式以及 Unity 遊戲引擎。

2021 年也不例外,下面是一些運用 WebAssembly 的新領域:

Disney+ 應用程式開發工具包使用 WebAssembly

網頁上釋出了一個簡化版的 Photoshop

微軟的飛行模拟器有一個基于 webassembly 的插件系統

随着功能和工具的改進,以及越來越多的商業産品使用 WebAssembly,我們開始看到 WebAssembly 在架構和正常 Web 上的應用。雖然應用的領域和産品還是很少,但是他的持續增長是令人興奮的。

2021 年對 WebAssembly 來說是偉大的一年,那麼我們對 2022 年有什麼期待呢?

預測 2022

我認為 2022 年一定會發生的事情是,WebAssembly 在幾乎所有領域的功能會得到進一步的增強和改善。這其中我最期待的是異常處理。

異常處理是許多程式設計語言必要的一個主要特性,是以它位于待辦事項清單的前列。Safari、Chrome 和 Edge 已經具備了此功能,并且 Firefox 和 Node.js 也在積極開發中。

由于低性能的 JavaScript 版本依然還能繼續使用,是以當你的子產品中需要用到異常處理的時候,如果可以使用性能更好的 WebAssembly 異常處理那麼就更新使用,否則就回退到使用 JavaScript 異常處理的版本。

正如前面提到的,包括 Firefox 桌面在内,幾乎所有現代的桌面端和移動浏覽器現在都支援了 COOP/COEP 響應頭。這些響應頭允許浏覽器安全地啟用共享緩存區,進而允許你的子產品使用 WebAssembly 多線程。

在現代浏覽器中,現在隻剩下 Firefox 移動端不支援這些響應頭,不過 Firefox 移動端已經規劃在 2022 年 2 月釋出的 97 版本中支援這些響應頭。

我預測此功能将在今年的 Safari 版本中實作。

我的理由是,Safari 在 2021 年增加了對 WebAssembly 的支援,WebAssembly 固定寬度 SIMD 規範現在已經标準化,而且 Xcode(蘋果的作業系統開發環境) 也已經支援了 SIMD。

尾部調用

為了支援 WebAssembly,一些程式設計語言不得不運用尾部調用,雖然很多事情都可以有變通的路徑,但其過程緩慢。除此之外,尾部調用在編譯優化和流程控制上也是有積極的作用。該提案已經完成一段時間了,但至如果想要進入到第四階段,就必須至少有 2 個廠商(Chrome、Firefox 或 Safari)實作此功能。Chrome 已經在一個版本标簽中實作了此功能,但在它達到第四階段之前 Chrome 并不打算正式釋出它。是以我們仍然必須等待至少再多一個廠商實作此功能。

并非各廠商不想實作此功能,而是他們都為各自認為更重要的事情而忙碌。是以人們正試圖提高此功能在各個廠商眼中的重要性和優先級。

支援多記憶體

此提案是使子產品擁有多個記憶體子產品。

多記憶體的一個使用場景是,子產品将一個記憶體區域作為自己的内部資料區域使用,将另外一個記憶體區域傳遞給某些需要寫入資料的子產品使用。通過此方式,你可以防止子產品内部資料因為外部子產品的異常寫入而發生錯誤。同時這種方式還可以很好的隔離敏感資料和共享資料,起到一定的安全作用。

另一個多記憶體的使用場景是,在 WebAssembly 的多線程中,你可以讓這些線程有一個共享的記憶體區域,同時将其他的子產品資料儲存到另外一個記憶體區域中。

如果你對多記憶體區域的使用場景感興趣,可以檢視多記憶體介紹(https://github.com/WebAssembly/multi-memory/blob/main/proposals/multi-memory/Overview.md)來了解更多使用場景。

目前此提案已經到了第三階段,同時還有很多引人注目的應用場景。是以我特别希望它在今年能正式釋出。

WASI(WebAssembly 系統接口)

在本文的前面提到,我預期子產品連結和接口類型兩個提案會在 2021 年完成。不過可惜,它們目前依然還在推進中,并沒有像我的預期那樣在 2021 年完成。

這些建議不僅僅是 WebAssembly 的一部分,它們還是建立元件模型必不可少的功能。根據此 WASI 的幫助文檔描述,元件模型和作業系統的程序模型類似,都是用來定義程序是如何啟動以及互相之間通信的。WASI 的在這裡扮演的角色就類似作業系統的 API 層。

是以,2022 年元件模型和 WASI 的接口類型提案都将持續發展。如果你對 WASI 的提案感興趣,可以通過 WASI 提案清單(https://github.com/WebAssembly/WASI/blob/main/docs/Proposals.md)檢視更多。

總 結

過去的一年裡,在提高 WebAssembly 性能方面,我們看到了 WebAssembly 多線程的共享緩沖區、固定寬度 SIMD 和異常處理等特性。同時,.NET6 中提高了對 WebAssembly 的支援,并且.NET 和 Uno 平台都通過增加 AOT,進一步提高 WebAssembly 的性能。

Safari 在 2021 年是一個大驚喜,他們在追趕其他浏覽器的 WebAssembly 支援上做了很多工作。

在 2021 年,我們看到更多的商業産品加入了使用 WebAssembly 的行列,同時,WebAssembly 也開始在大衆網絡上得到應用。

如此看來,2022 年必将會是 WebAssembly 發展的又一個好年份,因為那些現在還不支援的功能特性,很有可能在 2022 最終正式釋出且投入生産。

針對 WebAssembly 本身有非常多有趣的功能提案,同時位元組碼聯盟也将繼續助力 WebAssembly 在浏覽器以為場景的落地和功能更新。

如果你對 WebAssembly 功能支援的發展路徑有興趣的話,可以通過下面的網站進行了解。第一列顯示的是特性清單:WebAssembly 功能特性 RoadMap(https://webassembly.org/roadmap/)。

感謝特邀嘉賓 Gerard Gallant,他是“WebAssembly in Action”一書的作者,也是一名進階軟體開發人員,他寫了另一篇關于 WebAssembly 目前和未來狀态的綜合文章。

原文位址:

https://platform.uno/blog/the-state-of-webassembly-2021-and-2022/

繼續閱讀