【问题标题】:Is it more efficient to use find() rather than > for child selector in jQuery?在 jQuery 中使用 find() 而不是 > 作为子选择器是否更有效?
【发布时间】:2016-10-12 08:23:27
【问题描述】:

在 jQuery 中,我认为使用 实现 1 找到具有特定选择器的子 DOM 会更有效,如下所示:

var $dataTable = $('#' + tabId + ' > div.container > div.dataTableContainer > table.dataTable');

但是我的一位朋友告诉我,使用时效率会更高 实现2如下:

var dataTable = $('#' + tabId).find('table.dataTable');

参考other question,我发现实现2的效率可能低于:

var $dataTable = $('#' + tabId + ' div.container div.dataTableContainer  table.dataTable');

但是实施 2 会比 实施 1 更有效吗?

【问题讨论】:

  • 第一个代码由原生 javascript 搜索运行,第二个是 jquery 搜索。
  • 去寻找,在 jquery 的所有性能测试中,结果都是最好的,比 $('table.dataTable', $('#' + tabId)) 或选择器等上下文更快。跨度>
  • 没有。 1sd 给#tabId > .cont > .data > .table,2nd 给#tabId .table
  • > 仅表示直接后代,而 .find() 等效于 " "(空格) - 它将搜索所有后代。 > 的等价物是 .children()。如果您的顶级节点下有大量 DOM 元素层次结构,> 会更快。
  • 这应该显示选择器之间的差异:sitepoint.com/jsperf1

标签: javascript jquery


【解决方案1】:

document.querySelector() 与直接后代选择器 > 最快,.find() 最慢。

var tabId = "abc";

console.time(".find()");
var $dataTable = $('#' + tabId).find('table.dataTable');
console.timeEnd(".find()");

console.time("jQuery(), >");
var $dataTable = $('#' + tabId + ' > div.container > div.dataTableContainer > table.dataTable');
console.timeEnd("jQuery(), >");

console.time("document.querySelector()");
var $dataTable = document.querySelector('#' + tabId + ' div.container div.dataTableContainer  table.dataTable');
console.timeEnd("document.querySelector()");

console.time("document.querySelector(), >");
var $dataTable = document.querySelector('#' + tabId + ' >  div.container > div.dataTableContainer > table.dataTable');
console.timeEnd("document.querySelector(), >");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="abc">
  <div class="container">
    <div class="dataTableContainer">
      <table class="dataTable">
        <tbody>
          <tr>
            <td></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>

</div>

【讨论】:

  • 但作为旁注,document.querySelector() 只匹配一个节点。
  • 注意,OP 在问题中没有包含html。或者指定是否需要匹配多个元素。
  • @Kaiido &gt; 比没有更快。 .querySelector().querySelectorAll() 比 jQuery 方法快。
  • 您的测试仍然偏向于使用 document.querySelector() 返回 DOM 节点而不是 jq 集的事实。因此,您仍应将结果包装在 jq 对象中以进行更相关的比较。但它仍然会稍微胖一点,但没有什么比使用它更合理的了,恕我直言。最好是获得可读的代码,而不是让你赢得微秒的代码
  • 很抱歉给您带来了误解和我糟糕的英语。它应该意味着“高效”。
【解决方案2】:

我的猜测

在后台 $('#XXX whatever') 执行原生 document.queryselectorAll(),它将检查 文档中的所有元素,看它们是否匹配 '#xxx whatever'

$('#XXX').find('whatever') 首先执行document.getElementById('XXX'),找到带有id="XXX" 的元素,然后在该元素中执行queryselectorAll(),因此要测试的子元素更少,看看它们是否匹配'whatever'

但是这个猜测完全被真实数据否定了——看@guest271314的回答

【讨论】:

  • QSA 不会在我知道的任何浏览器中执行此操作:它将查找所有 whatever 元素(来自缓存),然后对每个元素沿着祖先链查找是否它们是匹配#XXX 的元素的后代。浏览器的选择器匹配优化得很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-28
  • 1970-01-01
相关资源
最近更新 更多