大家好,本文討論了Web 3D是否需要WebAssembly,結論是:
對於使用原生3D技術的程序員,需要;
對於使用Javascript語言的前端程序員,不需要,有其它方法可以達到接近WebAssdembly的性能。
WebAssembly是什么?
WebAssembly簡稱wasm,是一種數據格式,對應的文件后綴名為.wasm,文件由字節碼組成;
而Javascript對應的文件后綴名為.js,文件由字符串組成。
兩者都可以在瀏覽器上直接運行。
一份典型的.wasm 文件如下所示(引用自恕我直言,90% 的應用場景都不需要用WebAssembly!):
00000000: 0061 736d 0100 0000 0108 0260 017f 0060 .asm.......`...`
00000010: 0000 0215 0203 656e 7603 6d65 6d02 0001 ......env.mem...
00000020: 026a 7303 6c6f 6700 0003 0201 0107 0b01 .js.log.........
00000030: 0765 7861 6d70 6c65 0001 0a23 0121 0041 .example...#.!.A
00000040: 0042 c8ca b1e3 f68d c8ab ef00 3703 0041 .B..........7..A
00000050: 0841 f2d8 918b 0236 0200 4100 1000 0b .A.....6..A....
可以通過Emscripten等編譯器,將原生語言(如C++等)編譯為wasm程序。
比較wasm與js
優點
對於使用Javascript語言的前端程序員,wasm的優點為:
- 體積更小
白鷺引擎團隊測試過:
將大約300k左右(壓縮后)JavaScript邏輯改用WebAssembly重寫后,體積僅有90k左右。雖然使用WebAssembly需要引入一個50-100k的JavaScript類庫作為基礎設施,但是總體來看資源尺寸的優勢還是很大的。
- 執行性能高(但是通過JIT優化,js程序的執行性能接近wasm)
wasm屬於AOT: Ahead-of-Time compilation,即在執行前,通過編譯生成瀏覽器能夠直接執行的、優化過的字節碼,這樣瀏覽器在執行它時不需要進行編譯,性能高。
但是,因為chrome瀏覽器的v8引擎支持JIT: Just-in-Time compilation,所以js程序的執行性能接近wasm(對於Web 3D程序,性能熱點的邏輯會在主循環中多次被執行。而v8會在多次執行后,確定熱點代碼,會將其優化為字節碼;然后從下次執行開始,直接執行字節碼)
要提高js代碼在JIT中的性能,需要保證類型的健壯性,如不要輕易改變變量的類型
因為js是弱類型和動態語言,直接寫js代碼很容易造成類型混亂,降低JIT的性能,所以我們應該使用編譯為js的強類型語言(如Reason語言),通過編譯檢查來保證類型的健壯性。 - 更加安全
因為wasm文件是字節碼,無法直接閱讀,所以增加了安全性。
缺點
對於使用Javascript語言的前端程序員,wasm的缺點為:
-
需要熟悉C++等原生語言
因為wasm是由原生語言編譯而來,所以需要程序員學習原生語言,增加了學習成本 -
不能直接操作原生圖形API(如OpenGL),只能通過js調用WebGL
所以與其在wasm中調用webgl,還不如直接用js來調用webgl,這樣更方便,性能應該也差不多
參考資料
How to use WebGL shaders in WebAssembly:
When compiling, emscripten will map our code to the WebGL API.
WebAssembly 的出現是否會取代 JavaScript? - doodlewind的回答 - 知乎:
調 OpenGL 都要走回 JS 到 WebGL
- 增加了維護成本
我們通常用這種方案來應用wasm:一部分邏輯用wasm實現,負責需要高性能的密集計算;另一部分邏輯用js實現,負責dom操作和webgl調用。
這樣就需要同時維護wasm和js代碼,增加了成本。
結論
對於使用原生3D技術(如基於C++語言和DirectX、OpenGL等原生圖形API)的程序員
可以用wasm技術,將3D程序編譯為wasm文件,從而原生3D應用搬到瀏覽器上運行
對於使用Javascript語言的前端程序員
不需要用wasm技術,而是通過下面的方法來獲得接近wasm的性能:
1、使用強類型語言(如Reason)編譯為js。這樣可提高js代碼在JIT中的性能
2、把需要高性能的計算邏輯,放到worker線程中進行計算;或者使用WebGPU的compute shader,將其從CPU端移到GPU端進行計算,大幅提升性能。
關於WebGPU,可以參考 WebGPU學習
參考資料
恕我直言,90% 的應用場景都不需要用WebAssembly!
如何評論瀏覽器最新的 WebAssembly 字節碼技術? - 羅志宇的回答 - 知乎
WebAssembly在白鷺引擎5.0中的實踐