本文是圖說 WebAssembly 系列文章的最後一篇。若是您還未閱讀以前的文章,建議您從第一篇入手。html
2017 年 2 月 28 日,主流的四大瀏覽器達成了共識並宣佈 WebAssembly 的最小可行產品(MVP)已經完成。這是 WebAssembly 搭載在瀏覽器上的第一個穩定初始版本。git
這也爲瀏覽器提供了一個穩定的 WebAssembly 核心。雖然該核心還很差漢社區組正在計劃的全部功能,但它也確實提供了足夠的功能,使得 WebAssembly 快速且可用。github
從這一刻開始,開發者也能夠開始發佈 WebAssembly 代碼了。對於較早版本的瀏覽器,開發者能夠回退到使用 asm.js 版本的代碼。由於 asm.js 是 JavaScript 的子集,因此任何 JavaScript 引擎均可以運行它。
若是使用 Emscripten 的話,還能夠把相同的應用編譯爲 WebAssembly 版本和 asm.js 版本的代碼。web
即便是最初的發行版本,WebAssembly 也是高性能的。可是隨着問題的修復和新功能的添加,它在將來將會擁有更高性能。segmentfault
隨着瀏覽器逐步改進對 WebAssembly 的支持,性能提高也會慢慢的顯現。目前,瀏覽器廠商們正在獨自改進下面這些問題。瀏覽器
當前,在 JavaScript 中調用 WebAssembly 函數比想象的要慢。這是由於這個過程必須經歷一個稱爲彈跳(Trampolining)的過程。JIT 並不知道如何直接處理 WebAssembly,因此它必須把 WebAssembly 轉移到知道如何處理它的地方去。這在引擎內部是一個很慢的過程,該過程會創建用來運行 WebAssembly 代碼的準備過程。數據結構
這個種處理方式可能比直接由 JIT 處理慢 100 倍。併發
若是將一個大型任務交給 WebAssembly 模塊來完成的話,咱們可能不會注意到這種開銷。
可是若是咱們在 WebAssembly 和 JavaScript 之間來回屢次調用,那麼這個問題就凸顯出來了。dom
JIT 必須在更快的加載時間和更快的運行之間作出權衡。
若是花費更多的時間在編譯和優化,雖然能夠提高運行速度,可是也下降了啓動性能。函數
一個基本事實是,大多數的代碼的運行次數其實都還達不到須要優化的地步。
不過,目前有許多正在進行的研究,在尋找預編譯和這樣的基本事實之間的平衡點。
因爲 WebAssembly 並不須要推測數據類型,因此引擎也不須要在運行時監視這些數據類型的變化。
這也就給了咱們更多的選擇餘地,例如把編譯和運行並行化。
此外,最近新增的 JavaScript API 容許對 WebAssembly 進行流式編譯。也就是說,引擎能夠在 .wasm 還沒下載完成的時候就開始對已下載的內容進行編譯。
在 Firefox,咱們正在開發雙編譯系統。一個編譯器會提早運行,並把代碼優化工做作得至關不錯。等到運行代碼的時候,另外一個編譯器會在後臺進行全優化工做。一旦代碼優化完成,便會當即替換掉舊代碼。
WebAssembly 的設計目標之一是先支持小部分功能並同步進行測試,而不是從一開始就把方方面面都設計好。
所以,它還有更多功能值得期待,不過新功能還沒進行周全的考慮。只有全部瀏覽器廠商都積極參與才能把新功能寫進規範。
如下是一些新功能。
目前,WebAssembly 沒有任何方式可以操做 DOM 。因此咱們不能像使用 element.innerHTML
同樣,從 WebAssembly 裏更新一個 DOM 節點。
相反,必須經過 JavaScript 才能改變 DOM 節點。
也就是說,必須把新值返回給 JavaScript 調用方。或者在 WebAssembly 中調用 JavaScript 函數。這是能夠實現的,由於 JavaScript 和 WebAssembly 函數均可以作爲 WebAssembly 模塊的導入。
無論使用哪一種方式,繞道 JavaScript 確定比直接操做 DOM 要慢。這就致使了部分 WebAssembly 應用可能會所以而推遲發佈時間。
有一種提升運行速度的辦法是,使不一樣代碼同時並行運行。
不過這有時候可能會偷雞不成蝕把米,由於線程間通訊可能比任務自己耗費的時間還多。
可是若是可以在不一樣線程之間共享內存,那麼這種狀況就會好不少。爲此,WebAssembly 可使用 JavaScript 的新接口 SharedArrayBuffer
來實現內存共享。一旦瀏覽器開始支持 SharedArrayBuffer
,WebAssembly 工做小組就立馬能夠開始爲之制定相關標準。
SIMD(Single Instruction, Multiple Data)是「單指令多數據」的縮寫。它是實現並行化的另外一種方式。
SIMD 能夠接受一個大型數據結構(好比一個包含不一樣數值的向量),而後對其中的不一樣數據同時應用相同的指令。這種方式能夠大幅提高遊戲或者 VR 中的各類複雜計算。
這對普通的網頁應用開發者可能沒那麼重要。可是對於像遊戲等多媒體應用開發者就顯得尤其重要了。
不少語言都支持異常處理,可是 WebAssembly 還沒有有相關異常處理的規範。
若是你使用 Emscripten 編譯代碼,你會發現它會模擬某些編譯器優化級別的異常處理。
不過這會致使編譯變慢,可是你能夠經過 DISABLE_EXCEPTION_CATCHING
標誌來關閉它。
若是 WebAssembly 自己就可以處理異常,那麼這種異常模擬就不必了。
也有一些將來的功能並不會影響性能,可是卻能提高 WebAssembly 的開發體驗。
script
來加載模塊的功能。等到該功能完成後,把 <script src=url type="module">
這種標籤指向 WebAssembly 模塊也應該是可以支持的。現現在 WebAssembly 已經至關快速。隨着新功能和改進逐步實現,相信它必定能夠變得更快!