摘要:目前,是圍繞和用例設計的。多線程在單個線程上運行。目前不支持多線程。
本文由云+社區發表作者:QQ音樂前端團隊
在識別和描述核心元素的過程中,我們分享了構建SessionStack時使用的一些經驗法則,這是一個輕量級但健壯且高性能的JavaScript應用程序,以幫助用戶實時查看和重現其Web應用程序的缺陷。
這次我們來分析WebAssembly的工作原理,以及在如下幾個方面和JavaScript進行比較:加載時間,執行速度,垃圾回收,內存使用情況,平臺API訪問,調試,多線程和可移植性。
WebAssembly的功能WebAssembly(又名wasm)是一種高效的,低級別的編程語言。 它讓我們能夠使用JavaScript以外的語言(例如C,C ++,Rust或其他)編寫程序,然后將其編譯成WebAssembly,進而生成一個加載和執行速度非常快的Web應用程序。
加載時間為了加載JavaScript,瀏覽器必須加載所有.js文本文件。 WebAssembly在瀏覽器中加載速度更快,因為只有已編譯的wasm文件才通過互聯網傳輸。并且wasm是一種非常簡潔的二進制格式的低級匯編語言,文件更小。
執行目前Wasm 比本地代碼執行速度慢20%。這倒是一個令人吃驚的結果,不過,這是一種編譯到沙盒環境中的格式并且在很多約束條件下運行,以確保它沒有安全漏洞或者很難攻防這個漏洞。與真實的本地代碼相比,其實速度下降很小。但是,未來它會更快。
更好的是,它與瀏覽器無關 - 所有主要引擎都增加了對WebAssembly的支持,并且現在提供類似的執行時間。我們來看看簡單看看V8中發生了什么:
V8 Approach: lazy compilation在左邊,我們有一些JavaScript源代碼,包含JavaScript函數。它首先需要進行分析,以便將所有字符串轉換為標記并生成抽象語法樹(AST)。AST是JavaScript程序邏輯的內存表示。一旦生成這種表示,V8直接轉到機器碼。一般來說,只需要遍歷樹,生成機器代碼,便生成了編譯好的函數。從這個過程可以看出,這個階段并沒有編譯速度的優勢。 現在,我們來看看V8管道在下一階段的功能:
V8管道設計這次我們有TurboFan,V8的優化編譯器之一。當您的JavaScript應用程序正在運行時,很多代碼在V8中運行。TurboFan可以監控運行緩慢的內容,是否存在瓶頸和熱點以優化它們。它將它們推送到后端,這是一個優化的JIT,它可以優化那些非常耗cpu的代碼。 雖然它解決了上述問題,但是新的問題在于:分析代碼并決定優化哪些內容的過程也會消耗CPU。這反過來又意味著更高的電池消耗,特別是在移動設備上。 然而,wasm不一樣在于,它會被插入工作流程中,如下所示:
內存模型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個會話。
參考:
https://www.youtube.com/watch...
https://www.youtube.com/watch...
此文已由騰訊云+社區在各渠道發布
獲取更多新鮮技術干貨,可以關注我們騰訊云技術社區-云加社區官方號及知乎機構號
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101804.html
摘要:目前,是圍繞和用例設計的。多線程在單個線程上運行。目前不支持多線程。 本文由云+社區發表作者:QQ音樂前端團隊 在識別和描述核心元素的過程中,我們分享了構建SessionStack時使用的一些經驗法則,這是一個輕量級但健壯且高性能的JavaScript應用程序,以幫助用戶實時查看和重現其Web應用程序的缺陷。 這次我們來分析WebAssembly的工作原理,以及在如下幾個方面和Ja...
摘要:前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。利用降低三倍加載速度自推出之后,很多開發者都開始嘗試在小型項目中實踐,不過尚缺大型真實案例比較。 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目...
摘要:圖表中的比例并不代表真實情況下的確切比例情況。解析當到達瀏覽器時,源代碼就被解析成了抽象語法樹。解析過后抽象語法樹就變成了中間代碼叫做字節碼,提供給引擎編譯。目前為止,不支持垃圾回收。這就是為什么在大多數情況下,同一個任務比表現更好的原因。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId...
摘要:的目標是對高級程序中間表示的適當低級抽象,即代碼旨在由編譯器生成而不是由人來寫。表示把源代碼變成解釋器可以運行的代碼所花的時間表示基線編譯器和優化編 WebAssembly 那些事兒 什么是 WebAssembly? WebAssembly 是除 JavaScript 以外,另一種可以在網頁中運行的編程語言,并且相比之下在某些功能和性能問題上更具優勢,過去我們想在瀏覽器中運行代碼來對網...
摘要:目前正在開發兩個編譯器系統。這就意味著有很多功能還在襁褓之中,沒有經過徹底思考以及實際驗證。這些特性叫做未來特性。實現這一功能將會使用中的,而這一功能的實現將會提高程序執行的效率。目前瀏覽器在逐漸支持用標記來加載模塊。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58ce7fd3a6...
閱讀 1764·2021-09-28 09:43
閱讀 1116·2021-09-23 11:22
閱讀 2724·2021-09-14 18:05
閱讀 1827·2019-08-30 15:52
閱讀 2817·2019-08-30 10:55
閱讀 2013·2019-08-29 16:58
閱讀 1327·2019-08-29 16:37
閱讀 3037·2019-08-29 16:25