- 原文地址:WebAssembly: Easy explanation with code example
- 原文作者:Vaibhav Kumar
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:fireairforce
- 校對者:錢俊穎
WebAssembly: 帶有程式碼示例的簡單介紹
為什麼要用 WebAssembly?
背景:Web 和 JavaScript
毫無疑問,web 具有高度移植性並且與機器無關,這使其能成為一個真正通用的平臺。
Web 是唯一真正的通用平臺。☝️
JavaScript(JS)是 Web 開發的預設語言。它有許多原生的 Web API 例如(DOM、Fetch、Web-sockets、Storage 等等),並且隨著瀏覽器功能越來越強大,我們正在使用 JavaScript(或者其它能轉譯成 JS 的語言)來編寫更復雜的客戶端程式。
但是在瀏覽器上執行一些大型的應用程式時,JavaScript 存在一些限制。
JavaScript 的限制
- 不利於 CPU 密集型任務
- JS 基於文字而非二進位制,因此需要下載更多的位元組,啟動時間也更長
- JS 解釋和 JIT 優化會消耗 CPU 和電池壽命
- 需要用 JS 重寫已經存在的非 JS 庫、模組和應用程式
Web 開發社群正在嘗試克服這些限制,並通過引入 Web 開發新成員 WebAssembly 來向其它程式語言開放 Web。
在 2019 年 12 月 5 日,WebAssembly 和 HTML、CSS、JavaScript 一樣,成為了第四個 Web 語言標準,能在瀏覽器上執行。
Web Assembly (WASM)
WebAssembly 是一種能在現代 Web 瀏覽器中執行的二進位制程式碼,它使得我們能用多種語言編寫程式碼並以接近本地執行的速度在 Web 上執行。
WASM 的功能
- WASM 是一種不能由開發者編寫的底層語言,而是由其它語言例如 C/C++、Rust、AssemblyScript 編譯而來
- WASM 是二進位制格式,因此只用下載更少的位元組(開發者也有等效的文字格式,稱為 WAT)
- 與 JS 不同,WASM 二進位制檔案無需任何優化就可以解碼和編譯成機器程式碼,因為在生成 WASM 二進位制檔案時就已經對其進行了優化
什麼時候使用 WebAssembly。
- CPU 密集型任務,例如遊戲或其它圖形應用中的數學、影像和視訊處理等
- 在 Web 上執行舊的 C/C++ 庫和應用程式,提供了可移植性,並且避免了將 C/C++ 程式碼用 JS 重寫的需求
- 消除將原生應用程式和各種編譯目標作為單個 WASM 編譯的需求,可以使其通過 Web 瀏覽器在不同的處理器上執行
WASM 在這裡並不是要取代 JS,而是要與之一起工作。JavaScript 本身已經具有不錯的原生 Web API 集合,WASM 在這裡可以協助完成繁重的工作。
注意: 現代 JavaScript 引擎非常快速並且可以高度優化我們的 JS 程式碼,因此 WASM 軟體包的大小和執行時間對於簡單任務可能不是很有利。 在本文中,我不做任何基準測試,但請參考本文底部的參考資料,可以獲取基準測試連結。
怎麼使用 WASM(加深學習 ?)
讓我們參照上述步驟在 C 中建立一個程式,用來計算數字的階乘並將其作為 WASM 在 JS 中使用。
我們可以使用 Emscripten 將上面 C 函式編譯成 WASM:
emcc factorial.c -s WASM=1 -o factorial.html
複製程式碼
它會生成 **factorial.wasm**
二進位制檔案以及 html-js 粘合程式碼。這裡引用了輸出目標的列表。
有效的可讀文字格式 WAT 如下所示。
可以通過多種方式將 WASM 的二進位制資料傳送到 Web 客戶端,我們可以使用 javascript 的 **WebAssembly**
API 編譯二進位制資料來建立 WASM 模組然後例項化這個模組來訪問匯出的功能。
載入 WASM 程式碼最有效、最優化的方法是使用 WebAssembly.instantiateStreaming() 這個直接從流式基礎源編譯和例項化 WebAssembly 模組的函式。
以下是使用 **instantiateStreaming**
來呼叫之前生成的 factorial.wasm
檔案的示例程式碼,該檔案可以由我們的伺服器提供,也可以被我們的 Web 客戶端按需呼叫。然後,我們可以使用以下 JS 程式碼例項化接收到的 WASM 模組,並可以訪問匯出的 factorial
function。
想快速理解所說明的步驟而無需進行繁瑣的設定,可以使用 WASM fiddle。
瀏覽器支援
所有的現代瀏覽器(Chrome、Firefox、Safari、Edge)都支援 WebAssembly。點選此處以檢視最新的支援統計資訊。
IE 不支援 WASM。如果需要在 IE 中使用 C/C++ 程式碼,我們可以使用 Emscripten 將其編譯為 asm.js(JS 的一個子集)。
未來
正在實現對執行緒管理和垃圾收集的支援。這會讓 WebAssembly 更適合作為 Java、C#、Go 之類的語言的編譯目標。
參考資料
- webassembly.org/
- WASM Explorer
- Online WASM IDE
- WASM Fiddle
- Google code-labs tutorial
- Benchmarking reference
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。