2016:編寫高效能的 JavaScript

發表於2016-11-28

1591807771-58383e56e82aa_articlex

本文的初衷是想介紹如何利用些簡單的程式碼小技巧就能促進JavaScript編譯器的優化程式從而提升程式碼執行效率。特別是在遊戲這種對於垃圾回收速度要求較高,你效能稍微差點使用者就能見到白屏的地方。

Monomorphism:單態性

JavaScript中允許函式呼叫時候傳入動態引數,不過就以簡單的2引數函式為例,當你的引數型別、引數數目與返回型別動態呼叫時才能決定,編譯器需要更多的時間來解析。編譯器自然地希望能夠處理那些單態可預測的資料結構、引數統計等。

Constants:常量

使用常量能夠讓編譯器在編譯時即完成變數的值替換:

Inlining:內聯

JIT編譯器能夠找出你的程式碼中被執行次數最多的部分,將你的程式碼分割成多個小的程式碼塊能夠有助於編譯器在編譯時將這些程式碼塊轉化為內聯格式然後增加執行速度。

Data Types:資料型別

儘可能地多用Numbers與Booleans型別,因為他們與其他類似於字串等原始型別相比效能表現更好。使用字串型別可能會帶來額外的垃圾回收消耗。

Strict & Abstract Operators

儘可能使用===這個嚴格比較操作符而不是==操作符。使用嚴格比較操作符能夠避免編譯器進行型別推導與轉換,從而提高一定的效能。

Strict Conditions

JavaScript中的if語句也非常靈活,你可以直接在if(a) then bla這個型別的條件選擇語句中傳入隨意類似的a值。不過這種情況下,就像上文提及的嚴格比較操作符與寬鬆比較操作符一樣,編譯器需要將其轉化為多個資料型別進行比較,而不能立刻得出結果。當然,這並不是一味的反對使用簡寫方式,而是在非常強調效能的場景,還是建議做好每一個細節的優化:

Arguments

儘可能避免使用arguments[index]方式進行引數獲取,並且儘量避免修改傳入的引數變數:

Toxicity:這些關鍵字有毒

Toxicity

如下列舉的幾個語法特性會影響優化程式:

  • eval
  • with
  • try/catch

同時儘量避免在函式內宣告函式或者閉包,可能在大量的運算中導致過多的垃圾回收操作。

Objecs

Object例項通常會共享隱類,因此當我們訪問或者設定某個例項的未預定義變數值的時候會建立一個隱類。

Loops

儘可能的快取陣列長度的計算值,並且儘可能在同一個陣列中存放單個型別。避免使用for-in語法來遍歷某個陣列,因為它真的很慢。另外,continue與break語句在迴圈中的效能也是不錯的,這一點使用的時候不用擔心。另外,儘可能將短小的邏輯部分拆分到獨立的函式中,這樣更有利於編譯器進行優化。另外,使用字首自增表示式,也能帶來小小的效能提升。(++i代替i++)

drawImage

draeImage函式算是最快的2D Canvas API之一了,不過我們需要注意的是如果為了圖方便省略了全引數傳入,也會增加效能損耗:

 

相關文章