jQuery选择器的性能表现

3

HTML标记:

<div>

 <a id="foo"> </a>

</div>

jQuery:

$('div').each(function(){

 $('#foo', this).dosmth(); // 1
 $('#foo').dosmth();       // 2

});

哪种方法在运行dosmth时会更快?

3
值得问一下,但为什么您要遍历div,以查看它们是否包含具有特定ID的对象?在DOM中只应该有一个ID为“foo”的元素。 - brymck
6个回答

4
由于我们得到了各种答案,希望这里能提供一些澄清(请参考这里的示例):
  1. 最快 - 不需要循环。跳过$("div").each部分,直接执行$("#foo")。因为foo是一个ID,所以查找是瞬间完成的。
  2. 中等 - 在循环中使用$("#foo")。注意,你也不想这样做,因为它会为页面上的每个div执行函数(因此在具有大量div的较大文档上,这将是最慢的)。
  3. 最慢 - $("#foo", this)。上下文节点本来就没有用处,还要考虑到jQuery会首先将this构建成一个jQuery对象,并将其转换为$(this).find("#foo")。当然,这都是不必要的。

底线:在大多数情况下(例如有时确认ID是否在一个上下文中而不是另一个上下文中),使用上下文节点进行ID查找是不必要的。

以下是来自jQuery源代码的一些资源:

1
我更新了你的fiddle,还添加了一个document.getElementById('foo')。http://jsfiddle.net/tr4fz/4/ 它不是jQuery选择器,但值得提醒的是,尽可能使用这种方式通过ID检索元素是最快的方法。 - Jose Faeti

2

由于在DOM中,#id应该是唯一的,所以您的标记将无效(我假设您使用.each()基于超过一个<div/>

将ID更改为类并使用以下内容:

<div>
 <a class="foo"> </a>
</div>
<div>
 <a class="foo"> </a>
</div>

脚本

$('div').each(function(){
   $('.foo', this).dosmth(); //or $(this).find(".foo");
});

但是如果你只有一个id为foo的元素,使用id选择器会更快,并且你可以省略使用.each()

$('#foo').dosmth(); //or document.getElementById("foo");

1

仅通过id选择器来进行jQuery搜索是最快的方式,因为它使用了JavaScript中的getElementbyId方法。

因此,这是最快的方法:

$('#foo').dosmth();

如果您使用类似下面的上下文:
$('#foo', this).dosmth();

它被翻译成:

$(this).find('#foo').dosmth();

这样做会造成另一个无用的操作,因为你的 #foo 是唯一的。

敬礼,

Max


0
请阅读下面关于此答案的讨论或查看Bryan上面关于选择器速度差异的回答。

I would go with

   $('a#foo', this).dosmth();

Update But instead of retrieving all the divs before, I would check for only the desired one at the first time like this

$('div a#foo').each(function(){
}

1
@Jose,我不相信它更快,因为从JavaScript的角度来看,最快的方法是document.getElementById('foo')。我不知道jQuery是如何实现的,但认为在这种情况下使用getElementById是很合理的。我甚至认为第一种方法更慢,因为jQuery需要测试“this”上下文。 - Karolis
@Jose 这个问题是关于这个特定情况的性能。所以我认为 $('#foo').dosmth(); 是最快的方法 :) 但我还没有测试过。这只是我的想法。 - Karolis
最近关于这个主题又有一个问题在stackoverflow上提出:https://dev59.com/XlTTa4cB1Zd3GeqPwd-w - Jose Faeti
我很确定第一种方法是较慢的查找方式。你的方法不是直接使用 document.getElementById,而是基于 this 构建一个 jQuery 对象,然后运行 $(this).find("a#foo"),它会在 $(this) 中搜索 <a> 标签,然后使用 getElementById 在这些 <a> 标签中进行搜索。 - brymck
现在事情变得清楚了...我想保留这个评论讨论,因为我认为它可能会有用,但是我想在我的答案中加入一些内容,因为现在我发现它是错误的。这可以实现吗?还是应该完全删除答案? - Jose Faeti
显示剩余3条评论

0
$('#foo', this).dosmth();

这将在 div 上下文中搜索,而不是整个 DOM,这将使选择器更快。这只有在 DOM 很大时才有意义,否则,只需使用正常的选择器:$('#foo').dosmth();


0
  1. 如果你使用id,那么只会有一个元素。所以你可以直接使用:

    $('a#foo').dosmth();

  2. 你不需要使用each()来遍历每个div并获取其中的所有a#foo元素。这样做会浪费时间,没有必要创建循环。相反,请使用:

    $('a#foo').each(function(){ ... });

或者甚至可以只用:

$('a#foo').dosmth();

如果你想的话,也可以这样做:$('div a#foo').dosmth();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接