跳至主要内容

[note] WebAssembly

為什麼要使用 WebAssembly

直接使用現有的程式碼

透過 WebAssembly 可以直接使用現有的程式碼到 Web 中,例如 Rust, C, C++ 已經有寫好的工具,可以透過 WebAssembly 的方式直接在瀏覽器中被使用。

效能上的差異

差不多的 peak performance

實際上不論是 WebAssembly 或 JavaScript 都有差不多的 peak performance,它們底層都是透過同樣的引擎在做優化,且也都會產生底層用以執行的 machine code。

WebAssembly 的 performace 較穩定且可靠

但很大的差異在於,若瀏覽器引擎要針對 JavaScript 的程式碼進行優化的話,JavaScript 需要先被執行,因為在程式尚未執行前,引擎並不知道變數的型別是什麼。也就是說,JavaScript 的引擎需要先執行 JavaScript 的程式碼後,才有辦法優化它。這也是為什麼 JavaScript 的程式在執行時往往一開始會比較慢(稱作,warm-up 階段),接著才會越來越快。

相對的,WebAssembly 的程式碼不需要先被執行後才能優化,而是在 compile 完後就能取得優化過的 WebAssembly 程式碼。

因此,若同時衡量 JavaScript 或 WebAssembly 程式碼的效能時,JavaScript 的效能可能會隨著執行時間的不同而有差異(因為它是邊執行邊優化);但對於 WebAssembly 來說,效能的表現則較穩定。

JavaScript 的 de-optimization

因為 JavaScript 並非強型別的程式語言,因此同一個函式接收的參數有機會是不同型別,例如有時字串、有時是數字。一般在執行函式時,如果該函式總是接收字串做為參數,那麼該引擎會產生處理 string 的 machine code,此時若突然帶入了不同型別的變數到該參數中,JavaScript 引擎需要「fall back」來重新解析(interpret)、處理這件事,這會使得效能的表現突然下降而無法維持在峰值(peak performance),這樣的現象被稱作 de-optimizationde-opt

WebAssembly 可以對優化最可多控制

除了上述之外,WebAssembly 比起 JavaScript 更能控制底層記憶體的配置、garbage collection 的機制、不同 thread 間的 concurrency 等等。因此若對於效能有更極致的要求或控制時(例如,遊戲),使用 WebAssembly 可以有更好的效能。

Binary size

參考