Web 3D是否需要WebAssembly?


大家好,本文討論了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中的實踐


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM