WebAssembly 系列一:WebAssembly 介紹

WebAssembly 介紹

出現 WebAssembly 的契機

JS 語言存在的缺陷

  1. JS只包含64位浮點數(double雙精度浮點數),遵循IEEE754標準,這會致使運算不許確的問題(如:0.1 + 0.2),固然現今的解決方案也不少,如:mathjsTC39 BigInt、將結果經過toPrecision + parseFloat處理等;
  2. JS的弱類型可能致使混亂與Bug,現今能夠經過TS解決;
  3. JS不能像編譯語言同樣高效;
  4. 在以前,若要進行web開發必須使用JS,雖然業界有各式各樣的Transpiler,但歸根結底仍是將其它源碼編譯成了JS,受限於JS的特性

谷歌與火狐對支持編譯語言的不一樣實現

谷歌Native Client(NaCl)(已廢棄)

NaCl使用SFI技術,使瀏覽器能夠安全地運行原生代碼,並可使用CPU的所有功能,PNaClNaCl增長了可移植性c++

PNaClNaCl的編譯與運行git

PNaCl經過Pepper與瀏覽器JS之間通訊github

NaCl的廢棄web

除Chrome之外,其它瀏覽器廠商認爲使用NaCl(PNaCl),應用程序將運行在一個黑盒中,對其安全性產生質疑。最終2017年5月,NaCl被廢棄,取而代之的是WebAssemblychrome

火狐asm.js

asm.js爲開發人員提供了一種將c/c++源碼轉換爲JS的方法(JS的嚴格子集)。例如使用Emscripten,c/c++代碼能夠編譯爲asm.js,js引擎識別到asm.js將會將其直接轉換爲彙編,利用WebGL經過GPU執行asm.js,極大的提高運行速度。其次asm.js模塊也能夠與JS模塊交互npm

JS的AOT編譯api

asm.js是WebAssembly最小可行產品(MVP)的基礎瀏覽器

asm.js的缺點:asm.js是一個文本文件,在進行任何編譯前必須經過網絡傳輸,而Webassembly則採用二進制格式,其體積更小,所以傳輸效率更高緩存

WebAssembly誕生

2015年4月,W3C成立WebAssembly工做組,用於監督與規範WebAssembly提案,倡導瀏覽器廠商使用一致性的規範。安全

WebAssembly的目標

  1. 規範瀏覽器廠商協做;
  2. JS使用WebAssembly代碼像導入一個模塊同樣簡單;
  3. 不取代JS引擎,僅僅是爲其添加一個新特性。

WebAssembly實質

簡介

WebAssembly是一個底層虛擬機,.wasm 是基於堆棧虛擬機的二進制指令格式,WebAssembly的設計目標是編譯高級語言(c/c++/Rust等),提供可移植的結果,支持部署到web端及服務端

核心

  1. 核心規範
  2. JS API & Web API
  3. 二進制及文本格式(將文本格式代碼序列化爲AST最終編譯爲wasm二進制文件)

堆棧虛擬機

堆棧虛擬機由兩個元素組成:棧(數據結構)、指令,棧存在兩個操做:push、pop,遵循後進先出,棧還包括指向棧頂項的指針。指令表示要對棧裏面項執行的操做。

示例,下面ADD指令會彈出棧頂兩項,通過求和指令後,將結果推回棧:

WebAssembly編譯

WebAssembly的MVP專一於C/C++,因此編譯主要是經過Clang/LLVM/Emscripten等實現

WebAssembly語義階段

當瀏覽器獲取到.wasm文件(二進制),JS引擎將使用解碼棧解碼,將wasm文件轉換爲AST,執行類型檢查,並將其解釋爲執行函數。示例圖:

說明

階段 說明
Decoding 解碼,將二進制格式轉換爲模塊
Validation 驗證,對解碼後的模塊進行驗證(如類型檢查),以確保模塊良好且安全
Phase-1: Instantiation 實例化第一階段,經過Globals、Memories、Tables,生成初始化模塊實例,並調用start()函數
Phase-2: Invocation 實例化第二階段,導出函數:從模塊實例調用

應用場景

  • 圖像/視頻編輯
  • 遊戲
  • 音樂流媒體、緩存
  • 圖像識別
  • 直播視頻
  • VR & AR

雖然以上應用也可使用JS,但使用WebAssembly能夠極大的提高其性能,而且經過二進制文件能夠極大的減小js編譯後文件(例如React的bundle)大小,在頁面上加載實例化wasm模塊能夠加快代碼執行(WebAssembly自身線程)

限制

  • 暫時不支持GC,C/C++的內存管理構建在語言中,而JAVA使用GC(程序再也不使用的對象佔用內存將被自動回收);
  • 不能直接訪問DOM,能夠經過JS、Emscripten完成操做
  • 對老版本瀏覽器不兼容,當前支持Webassembly的瀏覽器

Emscripten

Emscripten是一個LLVM-to-JS的編譯器,其接受諸如Clang編譯產出的LLVM位碼輸出,並將其轉換爲JS。Emscripten是一種構建、編譯、運行asm.js的技術組合。

生成wasm模塊,可使用Emscripten SDK管理器:

其它

JS AST 示例

Webassembly 提案

相關文章
相關標籤/搜索