多領域試水,WebAssembly 距離大規模應用還有多遠?
2021 年 6 月 21 日,Scott Logic 發布了 2021 年 WebAssembly (以下簡稱 Wasm)用戶報告。報告中顯示 69% 的受訪者認為 Wasm 將對未來的 Web 開發產生非常大的影響,同時受訪者還預計 Wasm 將會對不同應用領域產生重要影響。

不難看出,作為一項相對年輕的技術,Wasm 本身還是吸引了不少眼球。但另一方面,也有開發者注意到,雖然 Wasm 目前在多個領域都有相應的落地實踐,但距離大規模應用還是有一定差距。甚至,還有部分開發者提出 “ Wasm 的聲音在這兩年漸漸弱了”,那么究竟這門技術的現狀如何?今年 Wasm 2.0 草案的發布是否會對其發展有所推動?展望未來 Wasm 的前景又是怎樣?帶著這些問題,InfoQ 采訪了 PayPal Staff Engineer 、《 深入淺出 WebAssembly 》的作者于航。
快速發展中的 Wasm
在開始探討 Wasm 現狀之前,我們先來回顧下它的歷史。
眾所周知,當年 Brendan Eich 大神只用了 10 天時間便發明出了 JavaScript ,隨后這門語言便一路躥紅,并且一直到現在 JavaScript 仍是互聯網技術領域里最流行的編程語言之一。不過,即便如此,這門語言還是存在其自身的短板,其中,變量的動態類型就經常被大家詬病,雖然這也是它簡單易用的原因之一,但相較于靜態類型語言而言,這一點確實會帶來額外的運行時性能開銷。
因此,為了提升 Web 應用的性能,Wasm 應運而生,2015 年 Mozilla 在 asm.js 的基礎上發布了 Wasm。不過,Wasm 的出現絕不是要成為一門新的編程語言,正如其官方定義提到,WebAssembly(縮寫為 Wasm)是一種基于堆棧式虛擬機的二進制指令集。Wasm 被設計成為一種編程語言的可移植編譯目標,并且可以通過將其部署在各類環境中(瀏覽器、k8s 等),以便為客戶端及服務端應用程序提供服務。
- 新的指令格式:本質上是一種虛擬 ISA,它基于堆棧式虛擬機的執行方式設計。同樣的一段指令可以在二進制與文本兩種格式之間互相轉換。其中,文本格式被存放在以 .wat 結尾的文件中,其內部以 “S- 表達式” 的形式組織各指令之間的具體執行順序。二進制格式被存放在以 .wasm 結尾的文件中,該文件可以直接被瀏覽器、虛擬機等 Wasm 引擎解析和使用;
- 可移植編譯目標:由于 Wasm 指令被設計為在虛擬機上執行,因此無論操作系統和其所在的具體硬件指令集架構如何,它都可以在各種設備上運行。并且,作為編譯目標,人們通常首先使用高級靜態語言來編寫相應的功能邏輯,然后再經由 Emscripten 等編譯器來將這些高級語言源代碼編譯為對應的 Wasm 指令代碼。
以上就是 Wasm 的誕生以及它的定義,“當下 Wasm 仍然處在快速發展的過程當中,截至其目前發展歷史來看,其中有兩個年份是比較關鍵的”,于航總結道:
第一個關鍵年份是 2017 年。2017 年 2 月,四大瀏覽器(Firefox、Chrome、Edge 和 Webkit)在 Wasm MVP(最小可用版本) 標準的設計上達成共識,“這是一個很好的現象,說明大家對 Wasm 這項技術的潛在價值是認可的”;2017 年 8 月,WebAssembly Working Group(以下簡稱 WWG) 成立,Wasm 正式成為 W3C 眾多技術標準中的一員;2017 年末,Mozilla 宣布四大瀏覽器(引擎)完全支持 Wasm MVP 版本的特性。可以看到,2017 年 Wasm 發展很快,“這時候,大家看到了一種趨勢,就是 Wasm 可能會對目前的 Web 技術格局產生影響”。
第二個關鍵年份是 2019 年。2019 年 3 月,Docker 創始人 Solomon Hykes 在 Twitter 上說了一段話,大概意思為“如果 WASM 和 WASI 早在 2008 年就存在,那么我們就不需要創建 Docker”。此話一出,在社區產生了非常大的反響,“這一次,Wasm 的潛在價值從 Web 逐漸開始向 out-of-web 的其他領域,比如云原生、AI 以及區塊鏈等領域開始傳播”;2019 年 12 月,W3C 宣布 Wasm 成為第 4 種 Web 語言,同時 Wasm 1.0 標準正式落地;也是在這一年,由個人和公司組成的團體——字節碼聯盟(Bytecode Alliance)也宣告成立,聯盟旨在通過協作的方式,來共同實現 Wasm 及 WASI 相關標準,并通過提出新標準的方式來共同打造 Wasm 在瀏覽器之外的未來。“我們常見的一些 Wasm 虛擬機,比如 Wasmtime、Lucet 等也都是由他們負責設計和研發的。”
總結來看,在這兩個關鍵年份集中發生了一些意義重大的事情,對這門技術的發展起到了重要的推動作用。
到了 2020 年和 2021 年,Wasm 本身標準方面并沒有出現比較大的動作,或許也是因為此,部分開發者認為“ Wasm 漸漸沒了聲音”。不過,據于航介紹,其實在 2020 年和 2021 年 ,Wasm 本身也是在不斷完善和發展中的:
在 Wasm 1.0 標準基礎上,各類圍繞 Wasm 的基礎工具不斷涌現,瀏覽器和基礎設施加快了 Wasm 標準的實現速度。“這里有個改變值得關注,開發者的聚焦點開始逐漸從標準本身移向了 Wasm 在工業界的實踐和應用。”
另外,WWG 也在不斷推進 Wasm 2.0 相關特性的設計和落地,在此過程中,官方研究人員開始更多地去思考這門技術和開發者之間的關系。例如,對于開發者來說,Wasm 最初的官方文檔比較晦澀難讀,意識到這個問題之后,WWG 進行了相關調整和優化。“可以看出,Wasm 官方也逐步開始從關注技術本身轉而去關注它的推廣和應用。”
最后到了今年,Wasm 2.0 草案正式發布,包括很多處于 Phase 3 的提案也正在被實現。總體而言,最近這幾年并沒有像前幾年一樣,有看似特別重要的節點,但就一門新技術來說,它自身的發展仍然是在持續有序地進行的。“各類瀏覽器廠商也正以超預期的速度去整合那些試驗性的 Wasm 特性,從中大家也可以看到它們在這門技術上的賭注”。
Wasm 應用現狀:多點試水
回顧這門技術的整體發展脈絡,與 Java、C++ 等歷經幾十年磨礪的技術相比,Wasm 還是比較年輕的,不過,這門技術本身受關注度頗高,也從側面反映出它還是具有潛力的。目前,也已在多個領域有相應的落地,本次采訪中,于航按照類別為大家進行了盤點:
- 多媒體方面。由于在多媒體中包含的圖像編解碼等過程大都需要大量數學運算,因此像視頻解碼 ogv.js、Photon 引擎等開源庫和應用都在其設計實現中使用了 Wasm 來加速 Web 上媒體資源軟解碼的速度:通過配合 Wasm 虛擬機本身的高性能,再結合多線程以及 SIMD 等技術,解碼速度相較之前單純使用 JavaScript 有著巨大的提升;除此之外,借助 Wasm 這樣一種中間格式,以往用 C/C++ 編寫的眾多算法編解碼庫也都可以相對簡單地被用在 Web 應用中。“多媒體可以說是目前凸顯 Wasm 在 Web 平臺上價值的最為重要的一類應用。”
- 編程語言方面。自 Wasm 出現后,諸多新興編程語言在設計之初就將它作為編譯目標,比如 Walt、Grain 等。
- Web 框架領域方面。眾多基于 Wasm 的試驗性框架出現,比如可以使用 Rust 構建前端應用的框架 Yew 和 Seed;可以使用 Go 構建前端應用的框架 Vecty 等等。“雖然這些框架處在不斷發展中,但受限于目前 Wasm 字節碼中還無法直接操作 DOM 這一問題,所以,它們的可用性還有待觀察。”于航補充道。
- 與仿真器相關的一系列應用方面,如 WasmBoy、Pinky 等等。這類應用主要依賴于 Wasm 的高性能,可以使得仿真器以較高的效率來在 Web 上模擬對應平臺 ISA 指令的執行。
除了在瀏覽器內部的應用之外,Wasm 在瀏覽器之外的應用場景也很多:
- 云原生領域,有 Krustlet、Embly、Kubeless 等。其中,Krustlet 使得 Kubernetes 可以支持調度 Wasm 類型的 Kubelet;Embly 和 Kubeless 則是兩個基于 Wasm 的 Serverless 框架。
- 游戲引擎領域。大家非常熟悉的 Unity 和 Unreal Engine 嘗試用 Wasm 技術將大型 3D 游戲移植到 Web 端。同時,Ammo.js、Defold 等一些基于 Wasm 構建的新興游戲開發引擎也陸續出現。
不僅在上述“熱點”領域,Wasm 還在物聯網、操作系統、AI、密碼學等領域均有相應的落地實踐,同時作為技術設施的編譯器和虛擬機應用也比較常見。不過于航也表示,這些領域的實踐更多是一種“有限”實踐,換句話說,本質上還沒有為該領域做出突出貢獻。
因此,目前 Wasm 應用試水的領域還是很廣泛的,但距離大規模的應用還有一定的距離,那么是否因為這門技術本身存在一定的局限性呢?對此,于航認為眼下的應用現狀與技術本身并無直接關系,具體原因還需要從不同角度來分析:
一方面,大部分互聯網公司對于新技術的采用是非常謹慎的,并且通常情況下,不會輕易改變自己原有的技術棧。個中緣由不難理解,老的技術棧由于發展時間較長,遇到問題可以相對輕松地找到對應解決方案,“即使在技術性能上稍微有些損耗,但這些損耗往往可以通過簡單地橫向擴展就得以解決,簡單來講就是用錢就可以解決。”
另一方面,對于互聯網公司來說,采用新技術則需要考慮多方面因素:第一,團隊現有人員的技術棧是否可以以較低成本使用這個新技術;第二,新技術的采用對現有組織架構的影響;第三,采用新技術帶來的價值是否能夠抵消它帶來的潛在風險等等。
在這種背景下,對大多數公司來說,現階段對 Wasm 還是持有一個相對謹慎的態度,更多的先嘗試將其用在相對較小、較初期的業務中。
解讀 Wasm 2.0 草案
今年 4 月, Wasm 2.0 草案正式發布,雖然作為一個草案,它不一定會得到 W3C 及其成員的認可,甚至隨時可能被其他文件更新、替換或棄用,但這本技術本身自帶的熱度還是使得這份草案關注度頗高。相比 Wasm 1.0,Wasm 2.0 草案中加入了很多值得關注的新特性,比如引用類型(Reference Types)、固定寬度的 SIMD(Fixed-width SIMD)、批量內存操作(Bulk Memory Operations) 等等。這里,于航也為大家詳細解讀了 2.0 草案:
- 引用類型(Reference Types)增加了新的名為 externref 的類型,它可用于直接引用宿主環境中的值。并且,新增加的如 ref.func、table.set 等指令很大程度上增加了 Wasm VM 與宿主環境的互操作性,為后續的 Exception Handling 和 GC 提案做了鋪墊。

- 固定寬度的 SIMD(Fixed-width SIMD) 提案為 Wasm 提供了固定 128 位的 SIMD 支持。這使得在處理一些特殊場景時,Wasm 可以利用向量化的能力,在一個指令下完成多個結果的計算過程。
- 批量內存操作(Bulk Memory Operations)提案提供了用于優化 memcpy 與 memset 這兩個常用的內存操作函數的指令,新增加的 memory.copy 指令可以更加高效地操作內存。
同時,本次草案中,大家還會關注到仍有一些在討論中的提案,包括:分支提示(Branch Hinting)、尾部調用優化(Tail Call)、異常處理(Exception Handling)、線程功能(Threads)、寬松 SIMD(Relaxed SIMD)等等。于航提到,他對這些新提案還是相當期待的,因為這些特性可以繼續優化 WebAssembly 在各個場景中的使用體驗。展開來說:
- 分支提示(Branch Hinting)、線程功能(Threads)、寬松 SIMD(Relaxed SIMD)、尾部調用優化(Tail Call)都是為了提升 Wasm 字節碼在特定情況下的執行性能,最終為了盡可能地讓 Wasm 的執行效率能夠最大化。
- 異常處理(Exception Handling)是為了解決支持異常處理的源語言在編譯到 Wasm 時,對異常處理的兼容性問題。
“本次草案的發布,更多的是為下一步 GC 等復雜提案的實現打下堅實基礎,”于航談到,他認為就現階段來看,2.0 草案的發布不會改變語言的寫法,甚至對于上層用戶來說,可能不會有太大感知,但是這次草案的最大意義正是為后續 Wasm 體驗的改進做了很多鋪墊,“大部分人可能會覺得這幾個提案無關痛癢,但本質上它們是后續幾個大提案實現的重要前提。”
Wasm 前景如何?
回到開頭,在 2021 年 Wasm 用戶報告中,不少開發者曾預計 Wasm 將會對 Web 開發以及不同應用領域產生重大影響。那么經過上述分析到底 Wasm 的前景如何呢?本次采訪的最后,于航談到判斷 Wasm 的前景的話還需要大家持續關注以下兩個方面:
第一,官方提案的進度。對于開發者來說,可以每周或者每個月去跟進 GitHub 上相關提案的推進進度,如果這些提案在不斷推進,則對這門技術來說是個很好的跡象,“至少能夠說明 Working Group 作為一個核心的官方團隊,是重視這個事情的。”
第二,基礎設施廠商的實現進度。對于 Wasm 廠商和基礎設施廠商來說,如果它們愿意花更多精力來實現 Working group 新的提案,前提一定是看好這門技術的,也能從側面說明 Wasm 的發展前景。
“大家可能會擔心,覺得現階段看不到 Wasm 的更多落地,但我覺得落地還是要關注加入 WWG 的大公司的實踐情況。”于航談到,不過,也可以預見的是,隨著這門技術標準和相關生態的逐漸完善,參與制定的互聯網領頭公司,比如 Google 等勢必會率先在自己的業務場景中采用 Wasm 這門技術,屆時,在這些巨頭的影響下,沒有直接參與標準制定的公司或者規模較小的公司也會逐漸將 Wasm 進行落地實踐。