OdinMonkey 的黃昏:告別 asm.js

Mozilla 已正式宣布,從 Firefox 148 開始,將在 SpiderMonkey 引擎中停止 asm.js 優化。雖然 asm.js 程式碼將繼續作為標準 JavaScript 運行,但曾經讓其達到接近原生速度的專用優化功能將預設停用,並最終會被完全移除。

此舉標誌著從一個巧妙的黑科技(hack)向正式 Web 標準的最終轉型。對於維護舊版網站的開發者而言,功能上的轉換是無縫的,但性能優化的喪失使得重新編譯為 WebAssembly (Wasm) 成為高性能網頁應用程式的唯一可行路徑。

asm.js 的傳承

asm.js 於 2013 年推出並在 Firefox 22 中發布,是 Mozilla 對於如何在網頁上執行原生速度程式碼挑戰的戰略性回應。當時,業界正努力尋求如何在不依賴專有插件或像 Google 的 Native Client (NaCl) 這樣的獨立沙盒的情況下,實現高性能執行。

asm.js 採取了一種極佳的方法:它定義了 JavaScript 的一個嚴格、靜態類型的子集。透過遵循這些規則,開發者可以編寫程式碼,讓 JavaScript 引擎能夠即時識別並直接編譯為原生機器碼。這實現了幾項里程碑式的成就:

  • 主流移植: 它實現了大型 C/C++ 程式碼庫(例如 Unity 和 Unreal Engine)首次成功移植到瀏覽器中。
  • 快速原型設計: Epic Citadel 演示程式在短短四天內就成功移植到網頁上,證明了網頁作為遊戲平台的潛力。
  • Wasm 的基礎: 最重要的是,asm.js 作為 WebAssembly 的概念驗證。透過展示靜態類型的二進位格式可以在瀏覽器中高效執行,它為正式的 Wasm 標準鋪平了道路。

為何現在進行轉型

隨著 WebAssembly 的廣泛採用,維持 asm.js 平行優化路徑的必要性已經降低。Mozilla 引用了兩個主要原因來解釋此次移除:

  1. 維護成本: 在 Wasm 旁邊同時維持 asm.js 的流水線需要耗費大量的工程精力。
  2. 安全性: 減少虛擬機器 (VM) 中的程式碼量可以減少整體的攻擊面,從而增強瀏覽器的安全性。

Mozilla 的內部命名慣例為這次轉型增添了一抹詩意。asm.js 編譯器(稱為 OdinMonkey)正迎來它的「Ragnarök」(北歐神話中的諸神黃昏)。取而代之的是,BaldrMonkey(優化型 Wasm 編譯器)和 RabaldrMonkey(基準型 Wasm 編譯器)將引領下一代網頁性能。

社群觀點與權衡

雖然官方宣布被框架化為一個成功的故事,但開發者社群強調了 asm.js 與 WebAssembly 之間存在一些細微的權衡。

「隔離」問題

某些開發者認為 Wasm 與 JavaScript 環境的嚴格隔離是一把雙面刃。由於 Wasm 無法在沒有 shim 的情況下直接呼叫 Web API,且在 JS 與 Wasm 之間的零拷貝緩衝區(zero-copy buffers)處理上存在困難,有些人認為 asm.js 的方法更具靈活性。

"I personally think this is a mistake... wasm is too isolated from javascript... You can't call most web apis from wasm."

性能邊際案例

雖然 Wasm 通常更快且產生的二進位檔更小,但一些開發者聲稱,對於特定且高度優化的任務(例如 SHA256 雜湊),asm.js 的實作可以仍然優於 Wasm 方案。

現實世界的影響:Figma 的案例

業界範例說明了 asm.js 在專業網頁工具演進中所扮演的關鍵角色。例如,Figma 最初是從 C++ 程式碼庫開始的。asm.js 是證明專業設計工具可以在瀏覽器中運行的關鍵技術。Figma 僅在建立穩定的付費客戶群後才轉向 WebAssembly,因為 Wasm 可以避免將 JavaScript 解析為抽象語法樹 (AST) 的開銷,從前進步了顯著的載入速度。

結論

OdinMonkey 的落幕不僅僅是移除一段舊有的程式碼;它象徵著 asm.js 實驗的成功。透過證明網頁可以處理原生速度的執行,asm.js 強制推動了瀏覽器的演進,並擴展了「網頁應用程式」的定義。雖然有些人可能會懷念直接的 API 存取與子集-JS 方法的靈活性,但業界向標準化、二進位格式的轉型,確保了更安全、更高效能、且更具通用性的網頁。

Sources