哪种jQuery选择方法更快?
我想知道使用jQuery与使用普通的CSS范围选择器进行选择时使用context参数是否有任何优势。
假设我有这个HTML:
All contacts
Jim Jones
(555) 555-1212
Bob Smith
(555) 555-1213
Dave Baker
(555) 555-1214
Pete Harrison
(555) 555-1215
George Donald
(555) 555-1216
Chris Root
(555) 555-1217
如果我想从联系人div中获取所有新联系人(标记为’new’类),哪种方法更快,更好地扩展等等。?
$('.contacts .new');
要么
$('.new', '.contacts');
的jsfiddle
更新
在答案和评论中散布着很多很棒的信息。 总结一下主要观点,在大多数浏览器中,当存在多个.contacts div时,单个选择器会更好地扩展。 在大多数浏览器中,两个选择器上下文方法更快,只有一个.contacts div存在。
从中获取的有用之处在于我们可以在选择具有id的元素内部时使用一种方法。
$('p:first', '#chapter2'); // get the first paragraph from chapter 2
并将单选择器方法用于我们从可能较大的元素组中进行选择的实例。
$('.chapter p:first-child'); // get the first paragraph from all chapters
在所有(我的)赔率中,似乎2号是最快的。
在这里查看
理论上, $('.contacts .new')
应该更好地扩展,因为它只对选择器引擎进行一次调用。 对于$('.new', '.contacts')
,至少对选择器函数进行两次调用 – 首先获取具有类名.contacts
所有元素,然后进一步调用返回的每个.contacts
元素。
总之,只要将更多的.contacts
元素抛入HTML中,第二种方法就需要一个循环,它会显着减慢。 如果您不想拥有更多.contact
元素,那么您应该使用更快的ID。
IIRC, $('.foo', '.bar')
$('.bar').find('.foo')
$('.foo', '.bar')
委托给$('.bar').find('.foo')
,所以第二个应该更快。
$('.foo', '.bar')
比$('.foo .bar')
更快的原因是因为它通过sizzle作为本机getElementsByClassName
执行。 在执行任何复杂逻辑之前,在代码的早期检查仅包含单个类名的选择器的情况。
更新 :就像我想的那样,使用find()稍快一点: http : //jsperf.com/jquery-selection-method/2
更新2 :我在jQuery的代码中查找了 – $('.foo', '.bar')
$('.bar').find('.foo')
委托给$('.bar').find('.foo')
– https://github.com/ jquery / jquery / blob / master / src / core.js#L171 。
在你的两个例子中,第一个选择器可能会更快。 但是,如果将上下文分配给变量,则使用第二种方法,它会更快。
contacts = $('div.contacts'); $('.new', contacts);
您可以在http://jsperf.com/jquery-context-with-tagname上查看结果。 如果你有一个更大的HTML文档,那么使用标记名称为类添加前缀也可能会产生更好的性能。
第二个没有记录 ,所以你根本不应该使用它。
context
参数应该是:
用作上下文的DOM元素,文档或jQuery
参考: http : //api.jquery.com/jQuery/
字符串既不是那些字符串。
因此,在使用at作为上下文之前,应该从选择器创建一个jQuery对象:
$('.new', $('.contacts'));
在进行两次jQuery调用时,这应该稍慢一些。 但是,两个表达式基本上都做同样的工作,因此差异不应该那么大。
编辑:
测试方法如何扩展: http : //jsperf.com/jquery-selection-method/4
显示浏览器之间的性能不同。 当你有一个.contacts
,单个选择器在大多数浏览器中.contacts
,除了Opera非常快。 使用多个.contacts
元素,单个选择器可以更好地扩展。
我得到的结果是第一个选择器$('.contacts .new')
大约快22%。
更新有趣的是,巴勃罗得到了相互矛盾的结果。 我想知道我的测试是否有问题。
更新2这是在Chrome 13上运行的