[譯] WebAssembly: How and why

Skandar-Ln發表於2018-08-22

如何在瀏覽器中執行原生程式碼,為什麼要這樣做,這樣做對Javascript和Web開發的未來有何意義

[譯] WebAssembly: How and why

在所有瀏覽器裡面,都執行著js程式碼,它們被js引擎解析和執行。然而,js並無法最理想地處理所有任務。這就是WebAssembly介入的地方。

WebAssembly是一種新的能在現代瀏覽器中執行的程式碼。為了更高的效能而被設計出來,它是一種低階二進位制格式,所以檔案不大能夠很快地被下載和執行。你不會直接去寫WebAssembly,而是把其他高階語言編譯為它。

Assembly通常是指與機器碼類似的人類可讀語言。機器碼是你的處理器才能理解的一堆數字。

Assembly languages and machine code

所有的高階程式語言都需要編譯為能在處理器上執行的機器碼。不同的處理器架構需要不同的機器碼和對應不同的Assembly。

Compiling source code for different processor architectures

不像它的名字那樣,WebAssembly不代表某種特定的Assembly語言,他不針對特定的機器。他是面向瀏覽器的,當你提供要在瀏覽器中執行的程式碼時,你不需要考慮它會執行在什麼樣的機器上。

WebAssembly as an intermediary compiler target

當瀏覽器下載了WebAssembly程式碼後會快速將它轉換成某臺機器的assembly。

WebAssembly擁有可讀的文字格式(.wat),但是二進位制格式是你真正交付給瀏覽器的(.wasm)。

WebAssembly textual and binary format

WebAssembly能讓你做的是將C,C++或者Rust的程式碼編譯為叫做WebAssembly模組的東西。你可以在你的web應用中載入它並通過Javascript呼叫。

它並非Javascript的替代品,它和js一同工作的。

WebAssembly module in an application

為什麼需要WebAssembly

想想你不得不在瀏覽器外使用軟體的場景:視訊遊戲、視訊編輯,3D渲染,或音樂製作。這些應用都要進行大量的運算並需要很高的效能。Javascript並不能提供如此的效能。

Javascript最初被設計來給Web提供一些輕量級的互動。就是為了讓人易學和好寫,但是並沒有從高效能角度去設計。近年來,瀏覽器們在解析Javascript上做了很多優化,有了很大的效能提升。

隨著效能的提升,能在瀏覽器做的事慢慢擴充套件。新的API帶來了可互動的影象,視訊流,離線瀏覽等等。所以一些從前只作為原生App的應用也出現在了Web上。現在你可以在瀏覽器上編輯文件,傳送郵件。但是某些場景對Javascript來說還是很吃力。

視訊遊戲是個巨大的挑戰,因為它們不僅需要協調音訊和視訊,還需要協調物理和人工智慧。如果能在Web上高效地執行遊戲的話,那麼我們就能夠將很多應用帶到Web上來。這就是WebAssembly要做的事。

為什麼Web如此吸引人

Web的美麗之處在於它就像魔法一樣能在任何地方執行。沒有下載和安裝。只需要點點滑鼠Web應用就能馬上出現。它比直接在計算機上下載和執行二進位制檔案更安全,因為瀏覽器提供了程式碼執行的安全環境。而且通過Web分享是一件很容易的事,你可以把連結複製到任何地方。

WebAssembly能帶來什麼

  • 速度
  • 可移植性
  • 靈活性

WebAssembly就是為了速度而設計的。它的二進位制格式比Javascript的文字格式小巧很多。因此可以很快地下載,在網路較慢的情況下尤為明顯。

並且也能很快地解碼和執行。Javascript是一種動態型別的語言,變數型別不需要事先定義,也不需要提前編譯。這使得js寫起來十分容易,不過這也意味著js引擎需要額外地做很多事。它需要在頁面執行的同時去解析、編譯然後優化程式碼。

解析js程式碼包括把純文字程式碼轉換成抽象語法樹(AST),然後轉成二進位制格式。WebAssembly直接以二進位制形式提供,解碼速度更快。不像Javascript,它是靜態型別的,引擎在編譯期間不需要推測將使用哪種型別。大多數優化都是在編譯原始碼期間,甚至在進入瀏覽器之前發生的。記憶體是手動管理的,就像C和C ++這樣的語言一樣,所以也沒有垃圾收集。WASM二進位制程式碼的執行時間僅僅只比原生程式碼慢20%

Relative time spent processing WebAssembly in JavaScript engine

設計WebAssembly的主要目標之一是可移植性。要在裝置上執行應用程式,它必須與裝置的處理器體系結構和作業系統相容。這意味著要為所有需要支援的作業系統和CPU的組合編譯原始碼。使用WebAssembly,只有一個編譯步驟,你的應用程式將在每個現代瀏覽器中執行。

Compiling native code to run on different platforms vs. compiling to WebAssembly

WebAssembly最令人興奮的是它為Web編寫帶來了更大的靈活性。到目前為止,JavaScript一直是Web瀏覽器中唯一完全支援的語言。使用WebAssembly,Web開發人員將能夠選擇其他語言,更多的開發人員將能夠為Web編寫程式碼。JavaScript仍然是大多數情況下的最佳選擇,但現在有一個在你需要更高效能時能夠選擇的方案。

目前完全支援的語言是C,C++和Rust,但還有很多其他語言正在開發中,包括Kotlin和.NET,兩者都已經提供了實驗支援。

它如何運作的

你需要一個將原始碼編譯為WebAssembly的工具。如C何C++你可以使用Emscripten。如果你有一個C語言寫的"Hello word",Emscripten會生成必要的檔案,你會得到一個WebAssembly模組和HTML以及JS檔案。

emcc hello.c -s WASM=1 -o hello.html
複製程式碼

Compiling C/C++ code to WebAssembly with Emscripten

你需要HTML和JS檔案,因為WebAssembly無法直接訪問任何平臺的API - DOM,WebGL,WebAudio等。要使用其中任何一個,即使要在頁面上顯示WebAssembly程式碼的輸出,您也必須通過JavaScript。

您可以將WebAssembly二進位制檔案視為普通的應用程式模組:瀏覽器可以獲取,載入和執行它們。您可以在JavaScript程式碼中呼叫WebAssembly函式,也可以在WebAssembly模組中呼叫JavaScript函式。

如果你現在想試試,無需安裝,你可以訪問webassembly.studioWebAssembly Explorer

現在能使用它嗎?

YES!

WebAssembly幾乎在所有主流瀏覽器中得到了支援。它目前在全球支援74.93%的使用者,82.92%的桌面使用者。我們可以使用Emscripten編譯為asm.js(JavaScript的一個子集,只使用數字(沒有字串,物件等))作為老版本瀏覽器的相容方案。

Browsers that support WebAssembly

目前已經有很多很棒的WebAssembly例子。如上文提到的難點:視訊遊戲,Unity和虛幻4都有可執行的demo。比如這個在Unity引擎執行的坦克遊戲和Epic的一個Demo

原文連結:WebAssembly: How and why

相關文章