[英]What is the fastest way to get a dom element?
我正在對我的代碼進行性能調優,並且驚訝地發現瓶頸不是dom節點插入,而是選擇。
這很快:
var row = jquery(rowHTML).appendTo(oThis.parentTable);
但隨后在“行”中獲取元素的速度很慢:
var checkbox = jquery(".checkbox input", row);
我需要在每一行中獲取復選框,以便我可以附加一個事件處理程序。 選擇該復選框是ALMOST 10X AS SLOW,因為插入整個父行。
我在這做錯了什么?
DOM操作使用本機函數來執行簡單操作。 瀏覽器廠商優化這些。 您正在從HTML構建行。 在內部,jQuery使用.innerHTML
來構建集合,然后將其修補到瀏覽器的超快速解析器中。
選擇比較慢,因為JS代碼需要重復遍歷DOM。 較新的瀏覽器具有本機選擇處理功能,可為基於選擇器的JS提供顯着的加速。 隨着時間的推移,這將不再是一個問題。
以下是有問題的查詢$(".checkbox input", row)
,如何分解:
row.getElementsByTagName('*');
elements[i].className
與/(\\s|^)checkbox(\\s|$)/
。 matched[i].getElementsByTagName('input');
這與jQuery 1.3不同,因為它的引擎以相反的方式通過選擇器,從獲取所有輸入元素然后測試父元素開始。
Rremember認為JS選擇器引擎實現了很多CSS選擇器規范,而不是實際可用於CSS(或由當前瀏覽器實現)。 利用這一點,以及對引擎的了解,我們可以通過幾種不同的方式優化選擇器:
如果你知道.checkbox
是什么元素類型:
$("td.checkbox input", row);
首先對類型進行過濾,然后對於僅對那些匹配進行類更快。 這不適用於非常小的元素子集,但在實踐中幾乎不是這種情況。
更簡單的選擇:
$("input[type=checkbox]", row);
一個循環比兩個循環快。 這只找到輸入元素,然后直接按類型屬性過濾它們。 由於從不使用sub / child-elements,因此也可以跳過unique(並且智能引擎會嘗試執行此操作,因為unique很慢)。
更直接的選擇器:
$("td:first.checkbox input", row);
如果更直接(YMMV),更復雜的選擇器實際上可能更快。
如果可能,將搜索上下文移動到表級別:
我的意思是,不是循環遍歷行,而是在每個行中搜索復選框,而是將它們留在循環之后,然后一次全部選擇它們:
$("tr td:first.checkbox input", table);
這樣做的目的是消除重復啟動選擇器引擎的開銷,而是一次性完成所有操作。 這里提供的是完整性,而不是我認為會帶來大量加速的東西。
不要選擇:
從位構建行,隨時分配事件。
var row = $( '<tr></tr>' );
var cell = $( '<td class="checkbox"></td>' ).appendTo( row );
$( '<input type="checkbox" name="..."/>' ).appendTo( cell ).click(/* ... */);
由於Ajax或其他模板無法控制,這可能是不可能的。 此外,速度可能不值得將您的代碼變成這種混亂,但有時這可能是有道理的。
或者,如果這些都不適合您,或者返回太多的性能增益,那么可能是時候重新考慮該方法了。 您可以在樹的上方分配一個事件偵聽器並在那里獲取事件,而不是每個元素實例:
$('table').change(function(e){
// you may want a faster check...
if ( $(e.target).is('input[type=checkbox]') ) {
// do some stuff ...
}
});
這樣,除非用戶實際請求,否則您不會執行任何操作。 最快的。 :-)
var checkbox = jquery(".checkbox input", row);
這是遍歷整個dom樹以找到復選框。 您可以通過將選擇器更改為可以使用瀏覽器本機getElementById功能的ID來加快速度。
var checkbox = jquery("#checkbox input", row);
您還可以使用行作為DOM搜索的起點,如下例所示。 現在你不再遍歷整個DOM樹來查找匹配的元素。
var row = jquery(rowHTML).appendTo(oThis.parentTable);
row.children(".checkbox input");
使用事件委托並將單個處理程序添加到父元素,而不是復選框本身。
jQuery通過live()
函數支持這個。
嘗試在輸入字段上放置一個類名。 這可能會更快。
原因是你的代碼遍歷所有.checkbox類,試圖找到該元素的輸入子元素並返回它。 我認為這個行動可能是你的罪魁禍首。
通過簡單地只查找輸入字段所具有的類的所有元素,您可能會看到一些加速。
嘗試使用Sly ,它強調性能。
獲取DOM元素的最快方法是使用純JavaScript並通過ID調用它。
var element = document.getElementById('element);
如果你正在尋找性能,jQuery選擇器非常慢。 在那里的例子中,它必須掃描完整的DOM樹並檢查CSS類等,以找到相關的節點。
使用本機DOM方法要快得多。 這里有一些有趣的庫性能比較:
http://ajaxian.com/archives/taskspeed-more-benchmarks-for-the-libraries-and-browsers
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.