JS 一些優化效能的小細節

凹凸卿發表於2017-04-24

Github部落格: github.com/aototo/blog
喜歡的朋友star 支援一下

Js高效能優化小結

謹慎使用閉包

由於閉包[[Scope]] 屬性包含與執行環境作用域鏈相同的物件引用,函式活動物件本來會隨著執行環境完畢後一同銷燬,但引入閉包,物件無法被銷燬。

閉包會造成更多的記憶體開銷,同時IE下還會造成記憶體洩露。

快取物件成員

在同一個函式中,如果存在多次讀取同一個物件成員,可以在區域性函式中儲存物件,減少查詢。

function getWindowWH() {
    var elBody = document.getElementsByTagName('body')[0];
    return {
        width: elBody.offsetWidth,
        height: elBody.offsetHeight
    }
}複製程式碼

同時也解決了屬性越深,訪問速度越慢的問題。

DOM 操作

訪問DOM的次數越多,程式碼執行的速度越慢,統一的儲存結果最後在一併輸出。 例子:

 function innerHTMLLoop() {
     var content = '';

     for (var count = 0; count < 10000; count++){
         content += 'a';
     }

     document.getElementById("idName").innerHTML += content;     
}複製程式碼

重繪(repaints)與重排(reflows)

當頁面佈局和幾何屬性改變時就需要"重排"

避免在修改樣式的過程中使用 offsetTop, scrollTop, clientTop, getComputedStyle() 這些屬性, 它們都會重新整理渲染佇列

  • 最小化重繪和重排, 儘量一次處理

    1. 使元素脫離文件流(隱藏元素
    2. 使用 documentFragment
    3. 將原始元素拷貝到一個脫離文件的節點中, 修改副本, 完成後再替換原始元素)

事件委託

當有很多元素需要繫結事件的時候,我們一個一個的去繫結事件是有代價的的,元素越多應用程式越慢。事件繫結不但佔用了處理時間,並且追蹤事件需要更多的記憶體,有時候很多元素是不需要,或者是使用者不會點選的,所以我們需要使用事件委託來解決沒有必要的資源消耗。

例子: 我們需監聽li的click事件,通過冒泡事件來獲取點選的物件。

<ul>
    <li index='1'>1</li>
    <li index='2'>2</li>
    <li index='3'>3</li>
</ul>複製程式碼
var ul = document.getElementById('ul');

ul.addEventListener('click', function(e) {
  var now_index = e.target.getAttribute('index');
  ...
})複製程式碼

迴圈效能

一般的for語句可能很多人都這麼寫

for(var i = 0; i < array.length; i++){
    ....
}複製程式碼

每次迴圈的時候需要查詢array.length,這樣不但很耗時,也造成效能損失。只要查詢一次屬性,儲存在區域性變數,就可以提高效能。

for(var i = 0, len = array.length; i < len; i++){
    ....
}複製程式碼

重寫後的迴圈根據陣列的長度能優化25%的執行時間,IE更多。所以平時書寫的時候還是要多加註意。同時還是要避免使用for-in迴圈。

條件語句

if-else 對比 switch, 當條件語句較多的時候switch 更易讀,執行的要更快。所以但條件少的情況下使用if-else,當條件增加時,更傾向於switch,會更佳合理。

避免使用構造器

通過避免使用eval()和Function()構造器來避免雙重求值帶來的效能消耗。比如:

eval('2 + 2');  複製程式碼

使用 Object/Array 直接量

直接量的速度回更快。


//bad
var myObject = new Object();
myObject.name = "xxxx";

//good
var myObject = {
    name: "xxxx"
}複製程式碼

相關文章