JavaScript與WebAssembly進行比較

本文由雲+社區發表

做者:QQ音樂前端團隊html

在識別和描述核心元素的過程當中,咱們分享了構建SessionStack時使用的一些經驗法則,這是一個輕量級但健壯且高性能的JavaScript應用程序,以幫助用戶實時查看和重現其Web應用程序的缺陷。 前端

此次咱們來分析WebAssembly的工做原理,以及在以下幾個方面和JavaScript進行比較:加載時間,執行速度,垃圾回收,內存使用狀況,平臺API訪問,調試,多線程和可移植性。編程

WebAssembly的功能

WebAssembly(又名wasm)是一種高效的,低級別的編程語言。 它讓咱們可以使用JavaScript之外的語言(例如C,C ++,Rust或其餘)編寫程序,而後將其編譯成WebAssembly,進而生成一個加載和執行速度很是快的Web應用程序。後端

加載時間

爲了加載JavaScript,瀏覽器必須加載全部.js文本文件。 WebAssembly在瀏覽器中加載速度更快,由於只有已編譯的wasm文件才經過互聯網傳輸。而且wasm是一種很是簡潔的二進制格式的低級彙編語言,文件更小。瀏覽器

執行

目前Wasm 比本地代碼執行速度慢20%。這卻是一個使人吃驚的結果,不過,這是一種編譯到沙盒環境中的格式而且在不少約束條件下運行,以確保它沒有安全漏洞或者很難攻防這個漏洞。與真實的本地代碼相比,其實速度降低很小。可是,將來它會更快。安全

更好的是,它與瀏覽器無關 - 全部主要引擎都增長了對WebAssembly的支持,而且如今提供相似的執行時間。咱們來看看簡單看看V8中發生了什麼:服務器

img

V8 Approach: lazy compilation

在左邊,咱們有一些JavaScript源代碼,包含JavaScript函數。它首先須要進行分析,以便將全部字符串轉換爲標記並生成抽象語法樹(AST)。AST是JavaScript程序邏輯的內存表示。一旦生成這種表示,V8直接轉到機器碼。通常來講,只須要遍歷樹,生成機器代碼,便生成了編譯好的函數。從這個過程能夠看出,這個階段並無編譯速度的優點。 如今,咱們來看看V8管道在下一階段的功能:網絡

img

V8管道設計

此次咱們有TurboFan,V8的優化編譯器之一。當您的JavaScript應用程序正在運行時,不少代碼在V8中運行。TurboFan能夠監控運行緩慢的內容,是否存在瓶頸和熱點以優化它們。它將它們推送到後端,這是一個優化的JIT,它能夠優化那些很是耗cpu的代碼。 雖然它解決了上述問題,可是新的問題在於:分析代碼並決定優化哪些內容的過程也會消耗CPU。這反過來又意味着更高的電池消耗,特別是在移動設備上。 然而,wasm不同在於,它會被插入工做流程中,以下所示:多線程

img

內存模型

img

WebAssembly可信和不可信狀態 例如,編譯成WebAssembly的C ++程序的內存是連續的內存塊,其中沒有「漏洞」。有助於提升安全性的wasm的特性之一是執行堆棧與線性內存分離的概念。在一個C ++程序中,你有一個內存堆,你從堆的底部分配,而後從堆頂增漲堆大小。這便產生一個不少惡意軟件利用的漏洞:用一個指針就能夠在堆棧內存中查找數據從而更改變量,而這些數據本是你不該該訪問到的。 異步

WebAssembly採用徹底不一樣的模型。執行堆棧與WebAssembly程序自己是分開的,所以您沒法在其中修改並更改變量等內容。並且,這些函數使用整數偏移而不是指針。函數指向一個間接函數表。而後這些直接計算的數字跳轉到模塊內部的函數中。它是以這種方式構建的,以便您能夠同時加載多個wasm模塊,造成多個索引列表,而且一切正常。 有關JavaScript中內存模型和管理的更多信息,能夠查看關於該主題的很是詳細的帖子。

垃圾回收

您已經知道JavaScript的內存管理是使用垃圾回收器處理的。

WebAssembly的狀況有點不一樣。它支持手動管理內存的語言。您能夠自定義在WASM上的垃圾回收模塊,可是這個比較複雜。

目前,WebAssembly是圍繞C ++和RUST用例設計的。因爲wasm是很是低級的,所以只有彙編語言上一步的編程語言才易於編譯。C可使用普通的malloc,C ++可使用智能指針,Rust使用徹底不一樣的模式(徹底不一樣的主題)。這些語言不使用GC,所以它們不須要全部複雜的運行時內容來跟蹤內存。WebAssembly對他們來講是天做之合。

另外,這些語言並非100%設計用於調用複雜的JavaScript事物,如DOM。在C ++中編寫整個HTML應用程序是沒有意義的,由於C ++不是爲它設計的。在大多數狀況下,當工程師編寫C ++或Rust時,他們的目標是WebGL或高度優化的庫(例如重數學計算)。

可是,未來WebAssembly將支持不附帶GC的語言。

平臺API訪問

取決於執行JavaScript的運行時,能夠經過你的JavaScript應用程序來訪問平臺相關的API。例如,若是您在瀏覽器中運行JavaScript,則您有一組Web APIs,Web應用程序能夠調用它來控制Web瀏覽器/設備功能並訪問DOM, CSSOM, WebGL, IndexedDB, Web Audio API等。

然而,WebAssembly模塊沒法訪問任何平臺API。一切都是由JavaScript調用的。若是您想訪問WebAssembly模塊中的某些平臺特定的API,則必須經過JavaScript調用它。

例如,若是你想console.log,你必須經過JavaScript來調用它,而不是你的C ++代碼。這些JavaScript調用的成本有所下降。

這並不老是如此。該規範將在將來爲平臺API提供wasm,而且您將可以在沒有JavaScript的狀況下發布您的應用程序。

Source maps

當您精簡JavaScript源代碼時,您須要一種正確方式調試它。這就須要Source Maps。基本上, Source Maps 是一種將組合/縮小文件映射回未創建狀態的方法。當您爲生產而構建時,同時縮小和組合您的JavaScript文件,您將生成一個包含原始文件信息的源映射。當您在生成的JavaScript中查詢某一行和列號時,能夠在返回原始位置的源地圖中執行查找。

WebAssembly目前不支持source maps,由於沒有規範,但最終會支持(可能很快)。 當您在C ++代碼中設置斷點時,您將看到C ++代碼而不是WebAssembly。

多線程

JavaScript在單個線程上運行。有不少方法能夠利用Event Loop並利用異步編程。

JavaScript也使用Web Workers,但他們有一個很是具體的用例 - 基本上,可能阻塞主UI線程的任何CPU密集計算均可以進入到Web Worker中來提升性能。可是,Web Workers沒法訪問DOM。

WebAssembly目前不支持多線程。可是,這多是將來的事情。Wasm將更接近本地線程(例如C ++樣式線程)。擁有「真實」的線程將在瀏覽器中創造出許多新的機會。固然,這將打開更多濫用可能性的大門。

可移植性

現在,JavaScript幾乎能夠在任何地方運行,從瀏覽器到服務器端甚至嵌入式系統。

WebAssembly被設計爲安全和便攜。就像JavaScript同樣。它將運行在支持主機的每一個環境中(例如每一個瀏覽器)。就像當年的Java的Applets,WebAssembly有相同的可移植性的願景。

哪些場景更合適使用WA

在WebAssembly的第一個版本中,主要關注CPU佔用大的計算(例如處理數學)。想到的最主流的用途是遊戲 - 那裏有大量的像素操做。您可使用您習慣的OpenGL在C ++ / Rust中編寫您的應用程序,並將其編譯爲wasm。它會在瀏覽器中運行。 看看這個(在Firefox中運行)

http://s3.amazonaws.com/mozil...

這是 Unreal engine.。

另外一種使用WebAssembly(性能方面)可能有意義的狀況是實現一些庫,這是一個CPU密集型工做。例如,一些圖像處理。

如前所述,因爲大多數處理步驟都是在編譯期間提早完成的,所以wasm能夠減小移動設備上的電池消耗(取決於引擎)。

未來,即便您實際上沒有編寫編譯代碼,您也可使用WASM二進制文件。您能夠在NPM中找到開始使用此方法的項目。

對於DOM操做和沉重的平臺API使用,使用JavaScript確實頗有意義,由於它不會增長額外的開銷,而且具備本地提供的API。

在SessionStack中,咱們不斷加強JavaScript的性能,以編寫高度優化且高效的代碼。咱們的解決方案須要提供超快的性能,由於咱們不能阻礙客戶應用的性能。將SessionStack集成到生產Web應用程序或網站後,它會開始記錄全部內容:全部DOM更改,用戶交互,JavaScript異常,堆棧跟蹤,失敗的網絡請求和調試數據。全部這些都在您的生產環境中進行,而不會影響產品的任何UX和性能。咱們須要大量優化咱們的代碼並儘量使其異步。

不只僅是庫文件,當在SessionStack中重放用戶回話時,咱們會渲染用戶瀏覽器中發生的全部事件,而且咱們必須重構整個狀態,容許您在會話時間線中來回跳轉。由於沒有更好的選擇,爲了作到這一點,咱們大量使用了JavaScript提供的異步機會。

藉助WebAssembly,咱們將可以將一些最繁重的處理和渲染轉換爲更適合做業的語言,並將數據收集和DOM操做保留爲JavaScript。

若是你想嘗試下SessionStack,你能夠免費開始。有一個免費的計劃),每個月提供1000個會話。

img

參考:

此文已由騰訊雲+社區在各渠道發佈

獲取更多新鮮技術乾貨,能夠關注咱們騰訊雲技術社區-雲加社區官方號及知乎機構號

相關文章
相關標籤/搜索