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() 這些屬性, 它們都會重新整理渲染佇列
最小化重繪和重排, 儘量一次處理
- 使元素脫離文件流(隱藏元素
- 使用
documentFragment
- 將原始元素拷貝到一個脫離文件的節點中, 修改副本, 完成後再替換原始元素)
事件委託
當有很多元素需要繫結事件的時候,我們一個一個的去繫結事件是有代價的的,元素越多應用程式越慢。事件繫結不但佔用了處理時間,並且追蹤事件需要更多的記憶體,有時候很多元素是不需要,或者是使用者不會點選的,所以我們需要使用事件委託來解決沒有必要的資源消耗。
例子: 我們需監聽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"
}複製程式碼