Mozilla臺灣研發經理陳侃如(攝影/洪政偉)

網頁技術如HTML加上JavaScript問世都已超過了20年,儘管衍生了各式各樣的應用,但執行速度向來是網頁應用的瓶頸,這也成了網際網路技術推動者極力想要客服的障礙。早在WebAssembly問世之前,就已有各種技術,嘗試來改善網頁效能問題。

例如Web早期時,微軟推出了ActiveX套件,讓開發者可以把C、C++的程式語言,經編譯後,轉換成瀏覽器可執行格式,「本質上,這些ActiveX程式碼仍然是原生格式。」Mozilla臺灣研發經理陳侃如表示,這個做法卻產生了許多安全性問題,因為該套件與瀏覽器在同一執行環境下運作,導致兩者會互相影響,例如介入瀏覽器本身的記憶體配置流程,產生記憶體溢位問題。

而在2011年時,Google嘗試要來解這個難題,推出了開源計畫Native Client(簡稱NaCl),該技術讓使用者可以在瀏覽器內的沙箱環境中,執行編譯後的C、C++語言。陳侃如表示,NaCl除了提供一組完整API外,也有定義一個Bytecode格式,開發者可以將C、C++程式,編譯至Google Chrome環境執行,「讓既有程式碼還可以繼續利用。」

不過陳侃如表示,NaCl專案的問題在於,該技術與Web環境相容性並不完善,原因在於,它提供一組與瀏覽器功能重複的API,「只是可以在瀏覽器環境執行」,所以開發者還必須額外下載NaCl,安裝在Chrome瀏覽器上執行。

WebAssembly前身就是Asm.js

歷經ActiveX及NaCl後,Mozilla基金會在2013年時,提出Asm.js,「Asm.js可以說是WebAssembly的前身」,陳侃如表示,它是一個特殊格式的JavaScript,在一般瀏覽器也都可以執行,但是針對Asm.js特別設計的瀏覽器,可以讓它效能最佳化。而Asm.js讓開發者的C、C++程式語言可以編譯成JavaScript程式碼,達到接近原生程式的執行效能。

例如,2015年JavaScript之父Brenden Eich來臺時,示範使用瀏覽器執行射擊遊戲,就是Mozilla跟遊戲引擎廠商Unity合作,利用Asm.js編譯遊戲引擎,並且在網頁環境執行。而Asm.js的成功,各個瀏覽器業者也開始合作,剔除Asm.js當中與JavaScript關聯較深的元件,「剩餘的部分就是WebAssembly。」

首先,顧名思義,WebAssembly這個名字包含了兩個重要元素:Web及Assembly,「也就是網頁瀏覽器所使用的組合語言,」陳侃如表示。

早在瀏覽器還未問世的時代,開發者在開發C、C++應用程式時,單純只是編譯成機器碼給電腦執行,而組合語言開發出來的程式,也向來代表了在執行效能上更有效率的程式。藉助WebAssembly這個命名,就是希望網頁應用也可以像組合語言開發出來的程式一樣快。

不過,究竟WebAssembly是如何超過前輩Asm.js,陳侃如解釋,該技術之所以可以更快,就在於瀏覽器可以「更快簡換指令集」,把程式語言編譯成硬體近乎可以直接執行的Bytecode,所以瀏覽器只需要進行轉換作業,程式碼馬上就可以變成機器語言。

而Asm.js雖然是JavaScript的最佳化子集,不過它也有規範開發者可以使用的參數類別。陳侃如舉例,像是Asm.js內建特殊的語法,限定參數一定得要整數、浮點數、布林值等。而利用Asm.js,瀏覽器就可以把它轉譯成機器語言,不需要進行參數類型的檢查,「但是JavaScript的特性使然,開發者可以丟任何參數給函數執行。」

而相比Asm.js,WebAssembly會限定函數可以執行的參數類型。陳侃如表示,一開始WebAssembly鎖定編譯C、C++語言的重要因素,「就在於這兩個程式語言也都支援整數、浮點數」,而WebAssembly最初就選定支援這兩個參數類型,「因為它們可以直接對應至底層硬體。」

此外,這兩個程式語言,除了具備偏向機器可讀的特性外,也是許多老舊應用程式所使用的開發語言,不過他表示,未來Mozilla也會讓WebAssembly功能擴充,支援更多程式語言。

除了限制WebAssembly所能處理的參數類型,在編譯作業上,Asm.js與WebAssembly也有相當差異。陳侃如解釋,使用Asm.js進行編譯工作時,JavaScript會被編譯成Bytecode,而Bytecode在執行時,系統還會對它執行JIT(Just in time)的編譯處理,讓Bytecode更一步最佳化,變成機器可讀的機器語言(Machine Code)。「而WebAssmebly直接省略掉前面的過程,直接結合JIT的運作方式,系統可以一邊編譯程式碼,一同執行。

能用LLVM編譯的程式語言,未來WebAssembly都可支援

此外,WebAssembly在支援C、C++語言時,也有使用Emscripten編譯器。陳侃如解釋,這個工具原先是讓開發者,可以把C與C++程式語言編譯成JavaScript。而在Asm.js問世之後,Emscripten也開始支援讓開發者,把C、C++程式語言編譯成Asm.js格式。而現在則更進一步,可以編譯成WebAssembly。Emscripten的底層是使用LLVM,而LLVM是一個編譯器的函式庫。未來,LLVM可以直接產生WebAssembly格式,這也代表,任何可以透過LLVM編譯的程式語言,都可以轉換成WebAssembly格式。

除了C、C++之外,現在WebAssembly也有支援Mozilla自家開發的Rust語言,「大部分可以被編譯至機器語言類型的語言,都可以很簡單的支援」,陳侃如表示,現在比較熱門的程式語言包含Swift、Objective-C、Golang,未來也都是WebAssembly支援的方向。

 

超詳細WebAssembly入門網站

開發人員想要快速上手WebAssembly技術,最簡單的方法就是打開Mozilla基金會建立的WebAssembly.org官網。在這個網站上,提供了最詳細的WebAssembly參考資訊,從基本的上手指南開始,到詳細的技術文件都有,不只是介紹WebAssembly的開發參考資料,還包括了如何編譯和部署(如何嵌入網頁)WebAssembly的步驟,甚至是可以將WebAssembly程式嵌入到非網頁應用中的方法都有,例如可以將wasm檔案嵌入到JavaScript VM,如Node.js環境中執行。另外該網站也列出主要的WebAssembly開發工具和軟體供開發者參考。

網站中也列出W3C的WebAssembly技術社群對於未來WebAssembly發展的藍圖,讓開發者可以一窺WebAssembly的下一步功能,還列出了可向WebAssembly社群求助或回報問題的聯繫窗口。

特別的是,WebAssembly官網上直接提供了一個2015年Unity波士頓大會發表的3D線上遊戲坦克大戰Tanks,這正是利用WebAssembly開發的雙人對戰遊戲,可以讓開發者先體驗一下,WebAssembly打造出來的網頁應用可以多流暢,就像是原生應用程式一般。還可以連結到Unity公司開發這個遊戲的指南,教你如何一步一步用WebAssembly來設計一套3D線上遊戲。


Advertisement

更多 iThome相關內容