JQuery each()函數如何優化循環DOM結構的性能
2024-05-06 14:20:38
供稿:網友
如果對jQuery這東西只停留在用的層面,而不知其具體實現的話,真的很容易用出問題來。這也是為什么近期我一直不怎么推崇用jQuery,這框架的API設定就有誤導人們走上歧途之嫌。
代碼如下:
$.fn.beautifyTable = function(options) {
//定義默認配置項,再用options覆蓋
return this.each(function() {
var table = $(this),
tbody = table.children('tbody'),
tr = tbody.children('tr'),
th = tbody.children('th'),
td = tbody.children('td');
//單獨內容的class
table.addClass(option.tableClass);
th.addClass(options.headerClass); //1
td.addClass(options.cellClass); //2
//奇偶行的class
tbody.children('tr:even').addClass(options.evenRowClass); //3
tbody.children('tr:odd').addClass(options.oddRowClass); //4
//對齊方式
tr.children('th,td').css('text-align', options.align); //5
//添加鼠標懸浮
tr.bind('mouseover', addActiveClass); //6
tr.bind('mouseout', removeActiveClass); //7
//點擊變色
tr.bind('click', toggleClickClass); //8
});
};
總的來說,這段代碼不錯,思路清晰,邏輯明確,想要做什么也通過注釋說得很明白了。但是按作者的說法,當表格中有120行時,IE已經反映腳本運行時間過長了。顯然從表現來看,這個函數的效率不高,甚至說極其低下。
于是,開始從代碼層面進行分析,這是一個標準的jQuery插件式的函數,有個典型的return this.each(function( ) { 。.. };);形式的代碼,如果作者寫下這段代碼的時候,不是照本宣科不經思考的話,就應該意識到jQuery的一個函數干了什么事。
簡單來說,jQuery.fn下的函數,絕大部分是一個each的調用,所謂each,自然是對選擇出來的元素進行了遍歷,并對某個元素進行了指定的操作。那么看看上面一段代碼,進行了多少的遍歷,在此就假設只選擇了120行,每一行有6列,另加上1行的表頭吧:
遍歷th,添加headerClass,元素數為6。
遍歷td,添加cellClass,元素數為6*120=720。
從所有tr中找出奇數的,需要對所有tr進行一次遍歷,元素數為120。
遍歷奇數的tr,添加evenRowClass,元素數為120/2=60。
從所有tr中找出偶數的,需要對所有tr進行一次遍歷,元素數為120。
遍歷偶數的tr,添加oddRowClass,元素數為120/2=60。
遍歷所有th和td,添加text-align,元素數為120*6+6=726。
遍歷所有tr,添加mouseover事件,元素數為120。
遍歷所有tr,添加mouseout事件,元素數為120。
遍歷所有tr,添加click事件,元素數為120。
為了方便,我們簡單地假設,在遍歷中訪問一個元素耗時為10ms,那么這個函數一共用了多少時間呢?這個函數共遇上了2172個元素,耗時21720ms,即21秒,顯然IE確實應該報腳本執行過久了。
知道了效率低下的原因,要從根本上進行解決,自然要想方設法來合并循環,初略一看,按照上邊代碼中注釋里的數字,至少以下幾點是可以合并的: