將jquery對象緩存起來在
for循環中,不要每次都要訪問數組的length屬性,我們應該先將對象緩存進一個變量然後再操作,如下所示:
代碼如下:
var myLength = myArray.length;
for (var i = 0; i < myLength; i++) {
// 要做的事
}
在循環外使用append
進行DOM操作是有代價的,如果需要往DOM中添加大量元素,你應該一次批量完成,而不是一次一個。
代碼如下:
// 別這樣
$.each(reallyLongArray, function(count, item) {
var newLI = '<li>' + item + '</li>';
$('#ballers').append(newLI);
});
//較好的做法
var frag = document.createDocumentFragment();
$.each(reallyLongArray, function(count, item) {
var newLI = '<li>' + item + '</li>';
frag.appendChild(newLI[0]);
});
$('#ballers')[0].appendChild(frag);不要在each()裡用$('#id')的選擇器,會有多次遍歷查找dom元素,效率極低用document.createDocumentFragment()來減少頁面的DOM結構改變的次數、刷新的次數
// 或者這樣
var myHtml = '';
$.each(myArray, function(i, item) {
html += '<li>' + item + '</li>';
});
$('#ballers').html(myHtml);
保持簡潔風格
代碼如下:
// 不理想
if ($ventfade.data('currently') != 'showing') {
$ventfade.stop();
}
if ($venthover.data('currently') != 'showing') {
$venthover.stop();
}
if ($spans.data('currently') != 'showing') {
$spans.stop();
}
// 較好的
var elems = [$ventfade, $venthover, $spans];
$.each(elems, function(k, v) {
if (v.data('currently') != 'showing') {
v.stop();
}
})
慎用匿名函數
匿名函數的約束到處都是一種痛苦。他們難以調試,維護,測試或重用。相反,我們可以使用對象封裝,將那些處理和回調函數組織並通過命名管理起來。
代碼如下:
// 不要這樣
$(document).ready(function() {...
$('#magic').click(function(e) {
$('#yayeffects').slideUp(function() {...
});
});
$('#happiness').load(url + ' #unicorns', function() {...
})
});
// 較好的
var PI = {
onReady: function() {...
$('#magic').click(PI.candyMtn);
$('#happiness').load(url + ' #unicorns', PI.unicornCb);
},
candyMtn: function(e) {
$('#yayeffects').slideUp(PI.slideCb);
},
slideCb: function() {...
},
unicornCb: function() {...
}
}
$(document).ready(PI.onReady);
優化選擇器
節點選擇和DOM操作, 根據給定的ID匹配一個元素總是使用#id去尋找element
代碼如下:
// 非常快
$('#container div.robotarm');
// 超級快
$('#container').find('div.robotarm');使用$.fn.find方法更快一些,因為第一個選擇器是無須經過選擇器引擎處理,在jquery中最快的選擇器是ID選擇器.因為它直接來自於Javascript的getElementById()方法,這是非常快,因為它是原產於浏覽器。如果你需要選擇多個元素,這必然會涉及到DOM遍歷和循環,為了提高性能,建議從最近的ID開始繼承。
具體指定選擇器的右側部分應該盡可能具體,左側則不需要那麼具體。
代碼如下:
// 未優化
$('div.data .gonzalez');
// 優化後
$('.data td.gonzalez');如果可以,盡量在選擇器靠右側的部分使用tag.class,而左側只有tag或者只有.class。
避免過度的具體
代碼如下:
$('.data table.attendees td.gonzalez');
// 不寫中間的會更好
$('.data td.gonzalez');清爽的DOM結構也有助於改善選擇器的性能,選擇器引擎可以少跑幾層去尋覓那個元素了。
避免使用無定向通配符選擇器
代碼如下:
$('.buttons > *'); // 極慢
$('.buttons').children(); // 快很多
$('.gender :radio'); // 無定向搜索
$('.gender *:radio'); // 同上
$('.gender input:radio'); // 這樣 好很多
使用事件委派
事件委派允許你為一個容器元素(例如,一個無序列表)綁定一個事件處理程序,而不需給容器內每個元素(例如,列表項)都去綁定。jQuery提供$.fn.live和$.fn.delegate。如果可能的話,你應該使用$.fn.delegate而不是$.fn.live,因為它省去了不必要的選擇需要,其明確的情況下(對$.fn.live的文檔的上下文),減少了大約80 % 的開銷。除了有性能提升的好處,事件委派也使你在往容器裡添加新元素時無需重新綁定事件,因為已經有了。
通過事件委派一次綁定多種事件,以減少事件冗余
代碼如下:
// 不好的 (如果列表裡面元素很多)
$('li.trigger').click(handlerFn);
// 較好的: event delegation with $.fn.live
$('li.trigger').live('click', handlerFn);
// 最優的: $.fn.delegate
$('#myList').delegate('li.trigger', 'click', handlerFn);
移除元素
DOM操作是慢的,你應該盡量避免去操作它。jQuery在1.4版引入了
$.fn.detach從DOM中去掉所有匹配的元素。
代碼如下:
var $table = $('#myTable');
var $parent = table.parent();
$table.detach();
// ... 添加大量的行到表格中
$parent.append(table);
.detach()和.remove()一樣, 除了.detach()保存所有jQuery數據和被移走的元素相關聯。當需要移走一個元素,不久又將該元素插入DOM時,這種方法很有用。
當大量元素修改CSS,應該使用樣式表
如果你在用$.fn.css給多於20個元素修改CSS,考慮一下添加一個style標簽,這樣可以速度可以提升60 % 。
代碼如下:
// 多於20個 明顯慢
$('a.swedberg').css('color', '#asd123');
$('<style type="text/css">a.swedberg { color : #asd123 }</style>').appendTo('head');
使用$.data而不是$.fn.data將$.data應用於DOM元素比直接調用jQuery選擇結果的$.fn.data要快上10倍.雖然,這要先確定你是理解DOM元素與jQuery選擇結果之間的區別的。
代碼如下:
// 常用
$(elem).data(key, value);
// 快十倍
$.data(elem, key, value);
別費時間在空白的選擇結果上了
jQuery將不會告訴你,如果你想運行的代碼在一個空選擇上,它會繼續運行,好像沒有什麼錯。影響性能。
代碼如下:
//太遭了,執行了三個方法後才意識到裡面是空的
$('#nosuchthing').slideUp();
// 較好
var $mySelection = $('#nosuchthing');
if ($mySelection.length) {
mySelection.slideUp();
}
// 最佳: add a doOnce plugin
jQuery.fn.doOnce = function(func) {
this.length && func.apply(this);
return this;
}
$('li.cartitems').doOnce(function() {
// make it ajax! \o/
});這層保護是適用於jQuery UI widget,因為即使操作的元素為空其開銷也不少。
定義變量
變量可以定義一個聲明而不是幾個
代碼如下:
// 老套寫法
var test = 1;
var test2 = function() {...
};
var test3 = test2(test);
// 新
var test = 1,
test2 = function() {...
},
test3 = test2(test);在自動執行的函數,變量的定義可以完全省掉。 (function(foo, bar) {...
})(1, 2);
條件判斷
代碼如下:
// 舊方法
if (type == 'foo' || type == 'bar') {...
}
// 好方法
if (/^(foo|bar)$/.test(type)) {...
}
// 查找對象
if (({
foo: 1,
bar: 1
})[type]) {...
}
作者:曾祥展
出處:學無止境 (http://www.cnblogs.com/zengxiangzhan/)