簡體   English   中英

獲得dom元素的最快方法是什么?

[英]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) ,如何分解:

  1. row.getElementsByTagName('*');
  2. for循環遍歷返回的每個元素(行中的所有元素)和測試elements[i].className/(\\s|^)checkbox(\\s|$)/
  3. for循環每個元素仍然存在並收集matched[i].getElementsByTagName('input');
  4. 獨特的最終系列。

這與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM