來源 | OSCHINA 社區
作者 | 京東云開發者-京東物流 潘維高
1 WebAssembly 是什么?
一種運行在現代網絡瀏覽器中的新型代碼,并且提供新的性能特性和效果
W3C WebAssembly Community Group 開發的一項網絡標準,對于瀏覽器而言,WebAssembly 提供了一條途徑,讓各種語言編寫的代碼以接近原生的速度在 Web 中運行。在這種情況下,以前無法以此方式運行的客戶端軟件等都將可以運行在 Web 中。
WebAssembly 設計之初就決定和 JavaScript 一起協同運行 —— 通過 JavaScript 中的 WebAssembly API,可以把 WebAssembly 模塊加載到一個 JavaScript 應用中并且在兩者之間互相調用。這樣可以在同一個應用中使用 WebAssembly 的高性能及 JavaScript 的高靈活性。
2 為什么需要 WebAssembly?
眾所周知 JavaScript 是解釋型語言,相比于編譯型語言需要在運行時轉換,所以解釋型語言的執行速度要慢于編譯型語言。
編譯型語言和解釋型語言代碼執行的具體流程如下:
因為解釋型語言每次執行都需要把源碼轉換一次才能執行,而轉換過程非常耗費時間和性能,也就導致在 JavaScript 背景下,web 無法執行一些高性能應用,如圖片剪輯、視頻剪輯、3D 游戲等。
根據 MDN 的定義,WebAssembly 是一種運行在現代網絡瀏覽器中的新型代碼,并且提供新的性能特性和效果。可以在現代的網絡瀏覽器中運行 - 它是一種低級的類匯編語言,具有緊湊的二進制格式,可以接近原生的性能運行,并為諸如 C / C ++ 等語言提供一個編譯目標,以便它們可以在 Web 上運行。它也被設計為可以與 JavaScript 共存,允許兩者一起工作。
3 WebAssembly 的工作原理
WebAssembly 不被解釋,而是由開發者提前編譯為 WebAssembly 二進制格式,如下圖所示。由于變量類型都是預知的,因此瀏覽器加載 WebAssembly 文件時,JavaScript 引擎無須監測代碼。它可以簡單地將這段代碼的二進制格式編譯為機器碼。
如果將每種編程語言都直接編譯為機器碼的各個版本,那么效率會很低。編譯器中稱為前端的部分會將所編寫的代碼編譯為一種中間表示 (intermediate representation,IR)。創建好 IR 代碼后,編譯器的后端部分會接收 IR 代碼,對其進行優化,然后將其轉換為所需要的機器碼。
由于瀏覽器可以在若干不同的處理器 (比如桌面計算機、智能手機和平板設備) 上運行,因此為每個可能的處理器發布一個 WebAssembly 代碼的編譯后版本會非常繁復。替代方法即取得 IR 代碼,并通過一個專門的編譯器來運行,這個編譯器將 IR 代碼轉換為一種專用字節碼并放入后綴為.wasm 的文件中。此時 wasm 文件中的字節碼還不是機器碼,它只是支持 WebAssembly 的瀏覽器能夠理解的一組虛擬指令。當加載到支持 WebAssembly 的瀏覽器中時,瀏覽器會驗證這個文件的合法性,然后這些字節碼會繼續編譯為瀏覽器所運行的設備上的機器碼。如下圖
WebAssembly 被設計為 JavaScript 的一個組件,不是它的替代品。雖然有些開發者試圖只用 WebAssembly 來創建整個網站,但這不是普遍情況。一般情況 JavaScript 仍然是更好的選擇。
4 WebAssembly 模塊內部
模塊中不同段的含義說明:
編譯器負責生成 WebAssembly 模塊的段,并將它們按照適當順序放置。
所有的段都是可選的,因此可能存在空模塊。
如果指定了已知段,那么它們只能出現一次并且要按照特定順序出現。
自定義段可以放置在已知段之前、之間或之后,用于指定不適用已知段的數據。
5 哪些語言可用來創建 WebAssembly 模塊?
現在 WebAssembly 的最小可行性版本(Minimum Viable Product,MVP)還沒有垃圾回收(garbage collection,GC),他限制了一些語言的使用。GC 作為一種后 MVP 功能正在開發中,實現之前,有幾種語言正在試驗 WebAssembly 支持,方式是將自己的 VM 編譯到 WebAssembly,或者在某些情況下將自己的垃圾回收器包含進去。
以下語言正在試驗或已經完成 WebAssembly 支持:
C 和 C++
Rust 正致力于成為 WebAssembly 的首選編程語言。
AssemblyScript 是一種新編譯器,它用來將 TypeScript 轉換為 WebAssembly。
TeaVM 是一個將 Java 轉譯到 JavaScript 的工具,現在也可以生成 WebAssembly 了。
Go 1.11 為 WebAssembly 增加了一個試驗性項目,其編譯后的 WebAssembly 模塊包含一個垃圾回收器。
Pyodide 是 Python 的一個項目,其中包含了 Python 科學棧的核心包:Numpy、Pandas 和 matplotlib。
Blazor 是微軟的實驗性項目,用于將 C# 引入 WebAssembly。
更多列表關注 github: WebAssembly 支持列表
相關案例:
TeaVM:它可以將 JVM 字節碼翻譯成 JavaScript 和 WebAssembly
我們有一段時間后端開始做一些前端開發,但是結果有時并不盡如人意,關鍵就在于我們的后端開發人員對前端無論是框架還是語法還是規范,都不是非常了解。這是在所難免的,但是因為業務需要又不得不做。
TeaVM 就為我們這種情況提供了一種解決方案,我們的后端開發人員依然使用自己熟悉的語言(java)進行開發。功能開發完成后再將_.class 或_.jar 文件通過 TeaVM 編譯成 wasm 或 JavaScript 供瀏覽器加載調用。
git:https://github.com/konsoletyper/teavm
官網:https://teavm.org/
6 WebAssembly 可以用在哪?
目前大多數瀏覽器廠商都已經支持 WebAssembly,包括 Chrome、Edge、Firefox 和 Safari。移動端 Web 瀏覽器也同樣支持。Node.js 也從版本 8 開始支持。
WebAssembly 不是 JavaScript 的替代品,而是它的一個補充,有些情況下 WebAssembly 是更好的選擇,有些情況下使用 JavaScript 會是一個更優的方案。與 JavaScript 在同一個 VM 運行可讓兩種技術相輔相成。
WebAssembly 為非 JavaScript 的開發者提供了一個新的道路,幫助他們在 web 中使用自己編寫的代碼。也讓不了解 C 或 C++ 等語言的 web 開發者可與訪問更新、更快的庫。個人理解 WebAssembly 也可用來優化某些庫的執行速度。
6.1 一些使用 webAssembly 的案例
Figma — 基于瀏覽器的多人實時協作 UI 設計工具:https://www.figma.com/
Google Earth https://earth.google.com/ - 17 年開始支持在 FireFox 打開,主要依賴 webAssembly。之前使用 Native Client 導致只能在 chrome 中運行
Magnum — 跨平臺的 OpenGL 圖形引擎 https://github.com/mosra/magnum
Egret Engine - 一款 HTML5 游戲引擎 https://github.com/egret-labs/egret-core/
Web-DSP — 使用瀏覽器就能即時制作多媒體影音特效 https://github.com/shamadee/web-dsp
7 WebAssembly 怎么用?
7.1 得到 wasm 文件手動引入
var importObject = { imports: { imported_func: function(arg) { console.log(arg); } } }; // 輸出 42 fetch('simple.wasm') .then(res => res.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(results => { results.instance.exports.exported_func(); });
7.2 得到編譯好的 npm 包引入執行
// alert(`Hello, ${name}`) const js = import("./node_modules/@jdl/hello-wasm/hello_wasm.js"); js.then(js => { js.greet("WebAssembly"); });
以下為 hello_wasm.js 文件編譯前源碼
// rust extern crate wasm_bindgen; use wasm_bindgen::*; #[wasm_bindgen] extern { pub fn alert(s: &str); } #[wasm_bindgen] pub fn greet(name: &str) { alert(&format!("Hello, {}!", name)); }
本文從為什么需要 WebAssembly、WebAssembly 的工作原理、哪些語言可用來創建 WebAssembly 模塊、WebAssembly 可以用在哪里 以及 怎么使用 幾方面簡要介紹了 webAssembly。如果之前沒有了解過 webAssembly,可以做一些簡要的了解。
審核編輯:湯梓紅
-
Web
+關注
關注
2文章
1256瀏覽量
69343 -
瀏覽器
+關注
關注
1文章
1016瀏覽量
35278 -
C++
+關注
關注
22文章
2104瀏覽量
73498 -
代碼
+關注
關注
30文章
4751瀏覽量
68357 -
javascript
+關注
關注
0文章
516瀏覽量
53793
原文標題:初探webAssembly
文章出處:【微信號:OSC開源社區,微信公眾號:OSC開源社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論