我們已經在 Windows 10 和 Microsoft Edge 大幅提升了 Chakra JavaScript 引擎的效能。目的是盡可能地利用現有硬件,讓你的 JavaScript 程式碼跑的更快。以便你創建的網頁能在 Microsoft Edge 中提供更好的使用者體驗。在開發過程中,我們團隊的目標之一,就是仔細觀察使用者回饋回來的數據,盡可能的讓在現有的網頁上面跑的更快。
就在不久前, 我們曾經為 Microsoft Edge 提供,在 Windows 10 中提升 Chakra JavaScript 引擎效能的各種方案。 改善效能是永無止境的追求,所以在本文中,我們來談一談,如何根據當今的網頁回饋回來的數據來提高 Chakra’s JIT 編譯器的效能。
現在的 JavaScript 編譯器都把內嵌函數當作是最佳化效能的關鍵因素。函數內聯是指把被呼叫的函數體插入調用的函數當中,就好像被調用的函數直接寫在調用的函數代碼中一樣,因此,能節省函數調用和返回的開銷(比如,寄存器的保存與恢復)。對於那些對效能要求較高的程式碼,函數內聯可以提高20-30%的效能。
在內嵌過程中, 編譯器會自動權衡是否要內嵌處理。 例如,有些時候,編譯器為了產生內聯程式碼,而花在收集上下文資訊的時間,比優化過後省下來的時間還要多。或者,試圖內聯其他上下文或腳本檔案的函數,付出的代價遠比從內聯得到的要高。
在開發 Windows 10 和 Microsoft Edge 過程中, 我們從現有的網站收集了一些數據, 以便更好的理解 Chakra 的內聯優化效果。我們從排名前10000 的網站中, 隨機選取f 3,000 個, 得到以下資料:
#在Chakra中只有30% 的函數呼叫進行內聯。 而有 48% o的函數, 由於呼叫與被呼叫分別存放在不同的腳本檔中, 無法內聯。 | 在另一個圖表中,超過 60% 的網站沒有內嵌。 |
在 Windows 10 和 Microsoft Edge 中, Chakra’s JIT 編譯器和和執行管道已經優化過, 所以, Chakra 現在能夠高效地內聯跨腳本文件的函數, 而不會丟失過多的性能。這種方式, 允許現有網站的 JavaScript 程式碼在 Microsoft Edge 上運作的更快。
ECMAScript6 將 const 常數值 引入了 Javascript 語言。 Const 常數在為 Javascript 開發者帶來語言和工具的便利性的同時,也讓 Javascript 編譯器可以最佳化查詢的新能。當一個屬性被定義為常數,編譯器可以該屬性在程式的整個生命週期都是不會改變的。在這個前提下,編譯器可以相應的最佳化,從而避免在這種屬性的查詢開銷。查詢開銷包括了檢查該屬性的類型, 結構,內部表現,找到該屬性實際儲存的值,以及檢查在程序的執行過程該值是否發生過變化等一系列開銷。而對於常數,編譯器不用執行以上任何一種檢查。
然後常數在網站正在日益增加,但是現存的大多數網站都還沒有試用常數結構。對於現在的網站,多數的常量都是被定義為一個全局變量,然後在代碼中到處試用. 在我們對10,000多家網站進行的一種實驗中,我們發現20%的網站都有定義整形常量的現象。而且每家網站有平均超過4種這種做法。
在Windows 10 和Microsoft Edge 中,我們優化了Chakra 的解析器和JIT 編譯器,用於識別聲明的非常數整數變量,這些變量在程式運行期間都有定義,但是沒有變化。一旦鑑別出來,Chakra 的 JIT 編譯器產生的程式碼就可以大幅減少循環消耗,因為這樣的全域變數在整個程式運行期間它們的值和形狀都沒有改變。因此將面向效能的 ECMAScript 6 中關於常數聲明的價值主張延伸到今天常數是如何廣泛地應用在網路中。
在今天,使用 try-catch 是非常普遍的。但是,在實務上並不建議使用 try-catch,尤其對於那些對效能很敏感的程式碼。 Try-catch 程式碼很難被最佳化,因為 try-catch 區塊中的大對數操作會導致異常,然後被捕獲。這種方式使 JIT 編譯器很難得到一個精準的模型。不同的技術需要使用不同的模型,這導致執行引擎需要創建額外的開銷來維護不同的模型。
我們所做的資料擷取實驗是基於4500個熱門網站的,就此了解有超過96%的網站會拋出JavaScript異常。實際上,超過50%的站點會拋出超過10個以上的JavaScript異常。
直到Windows 10,Chakra都沒有最佳化try-catch區塊內的程式碼。在Windows 10和Microsoft Edge中, Chakra的編譯器現在可以抽象化try-catch程式碼區塊內的程式碼和JIT最佳化的程式碼。這種情況下異常不會被拋出,Chakra現在執行try區塊內的程式碼幾乎與普通的JIT程式碼一樣(這就好像try-catch不存在一樣)。
現今的Web 通常都使用了minified JavaScript 程式碼,這帶來了一個優勢,即減少了客戶端(瀏覽器)顯示內容的大小。在 Windows10 release 版本中,在調查一個特殊的效能問題的時候,我們發現一件事情,一些使用 minified JS 程式碼(minified JS 使用 UglifyJS)的實例,效能不如未使用 minified JS 的實例。在某些情況下,開發者在使用 minified JS 的過程中,使用了一些我們認為開發者通常不會使用的程式碼模式,這也是 Chakra 還未做最佳化的原因。於是,我們做了一個快速的試驗,用來查看 Web 上使用 minified JS 的情況。我們從 10,000 個站點中隨機採樣了 4,000 個站點,以下是我們發現的資訊:
Minification on Top 4000 sites | ||
#95% of the sites had some form of minified code | Out of the 95%, 77% sites had some code that was minified using UglifyJS | Out of the 95%, 47% of the sites used jQuery minified via UglifyJS |
這個試驗確認了,在Web 中minified JS 程式碼的使用非常流行,由於UglifyJS 存在於其它程式碼之中,所以它也非常廣泛的應用於現今的Web 之中。因此,在 Windows10 和 Microsoft Edge 瀏覽器之中,我們增加了用來提升內嵌的新途徑。同時,我們優化了在 Chahra 的 JIT 編譯器的一些探索法,用來確保 minified JS 程式碼運行的盡可能和沒有使用 minified JS 程式碼的版本一樣快–即便不比它們更快。基於這些改變,我們測試過,使用 UglifyJS 的單一程式碼模式的 minified JS 效能提升了大概20-50%。
在Web中使用陣列的情況是非常普遍的。除了提供polyfills和幫助函數,許多非官方的JavaScript函式庫,嘗試著提供JavaScript語言一些標準陣列內建函數的更快的實作。理想的情況下,對於內建的部分,所有的瀏覽器都應該足夠的快,這樣,庫就可以更集中於提供polyfill和幫助API,而不是擔心在不同瀏覽器之間修復內建部分的效能問題。另一方面,開發者也不應該,只是為了讓一些所有JavaScript引擎實現的基本內建部分運作的更快,而不得不使用一個函式庫。
儘管我們離上述的理想情況很遠,在最近的一個資料收集的試驗中,我們嘗試著估計量在現今Web中使用最多的ECMAScript 5 的內建部分。這個試驗從10,000個站點中隨機採樣大約4000個站點。我們發現,其中使用最多的前三名分別是: Array#indexOf, Array#map 和 Array#forEach。
鑑於Array內建函數在Web中的廣泛使用,在Windows10 和 Microsoft Edge中,當引擎遍歷一個陣列時,Chakra優化了取得值的過程。當數組中存在「洞」(hole,即不存在元素)的時候,這項優化有助於去除訪問原型鏈(extraneous overhead)和根據序號查找數值的時候的外部開銷。這項優化提升了Chakra和Microsoft Edge中內建的 ECMAScript5 Array#indexOf 函數超過5倍的效能。
在下面列出來的許多優化中都是來自於網絡上面已經存在的數據,幫助站點在Microsoft Edge 上面運行的更快。我們不願意去討論關於虛擬測試,還是經常被問及(Charkra)是如何在 Mircorsoft Edge 上獲得如此高的 Javascript 測試性能的。下面的圖是我們目前為止已經提交的IE11同其他流行的瀏覽器相比在 Microsoft Edge 上得到性能加強的 Javascript 測試結果。
所有的測試基準都是在64位元Window 10 技術預覽版上面運行的64位元瀏覽器收集而得.
系統資訊:HP Compaq 8100 Elite with Intel(R) Core(TM) i7
CPU 860 @ 2.80GHz (4 cores), 12GB RAM
這張圖說明了什麼?在 Microsoft Edge 上 Charkra 比 IE11 更快。仔細觀看,Chakra 在以下的這些的測試中通過Microsoft Edge Microsoft Edge Apple 超過了1.5倍
Octane 2.0 ##注意:你會好奇為什麼在這個效能測試中是了64 位元瀏覽器而不是32 位元瀏覽器,原因是不像IE11 Microsoft Edge 需要運行在64 位的平台下。所有的流行的 64 位元 Javascript 引擎相比較 32 位元平台運行有一點點慢,選擇 64 位元平台可以提供一些安全特性,在這篇部落格中得到了補充。
然而在贏得了跑分中並沒有使我們感到很滿意,關鍵是為了提升 Javascript 的性能從 IE11 開始 Microsoft Edge 已經走過了很長的一段路程,就像測試已經存在了。如我們開始提到的,性能是一個不懈的追求。我們會繼續挖掘 Javascript 在 Microsoft Egde 中得效能極限。請繼續保持回饋幫助我們提升。您可以在網站上提交 bug,在用戶之聲上提交反饋,或者在 twitter 上面的 @MSEdgeDev 為我們提供援助。
– Gaurav Seth, Principal PM Lead, Chakra
#
以上是詳細介紹在Microsoft Edge提供快速的JavaScript效能(圖)的詳細內容。更多資訊請關注PHP中文網其他相關文章!