在 jQuery 中查找元素的最有效方法
Posted
技术标签:
【中文标题】在 jQuery 中查找元素的最有效方法【英文标题】:Most efficient way to find elements in jQuery 【发布时间】:2010-09-29 18:15:16 【问题描述】:如果我有一个我只应用于表单元素的 CSS 类,例如:
<form class="myForm">
这两个 jQuery 选择器中哪个最有效,为什么?
a) $('form.myForm')
b) $('.myForm')
【问题讨论】:
【参考方案1】:编辑:以下结果适用于 jQuery 1.2.6,可能在 Firefox 3.5 中。浏览器和 jQuery 本身的速度改进几乎使这些信息过时了。
我刚刚写了一个快速基准测试:
在一个包含 4 个表单和大约 100 个其他元素的页面上: 使用$('form.myForm')
10000 次耗时 1.367s
使用$('.myForm')
10000 次耗时 4.202 秒 (307%)
在只有 4 个表单且没有其他元素的页面上:
使用$('form.myForm')
10000 次耗时 1.352s
使用$('.myForm')
10000 次耗时 1.443s (106%)
似乎搜索特定名称的元素比搜索特定类的所有元素要快得多。
编辑:这是我的测试程序:http://jsbin.com/ogece
程序以 100 个<p>
标记和 4 个<form>
s 开始,运行两个不同的测试,删除<p>
标记并再次运行测试。奇怪的是,当使用这种技术时,form.myForm 更慢。自己看一下代码,然后按照自己的意愿编写代码。
【讨论】:
也许可以在 pastebin.me 或 jsbin.com nickf 上提供测试用例? 可能还取决于浏览器以及原生支持哪些 CSS 选择器。【参考方案2】:正如 redsquare 已经提到的,选择算法在以后的 jQuery 版本中发生了变化(部分原因是对 getElementsByClassName 的支持)。此外,我使用迄今为止最新的 jQuery 版本 (v1.6) 对此进行了测试,还添加了一个测试 document.getElementsByClassName 以进行比较(至少在 Firefox 4 和 Chrome 中有效)。
Firefox 4 中的结果是:
// With 100 non-form elements:
$('.myForm') : 366ms
$('form.myForm') : 766ms
document.getElementsByClassName('myForm') : 11ms
// Without any other elements:
$('.myForm') : 365ms
$('form.myForm') : 583ms
document.getElementsByClassName('myForm') : 11ms
接受的答案已经过时(仍然可以通过搜索“在 jquery 中查找元素的有效方法”之类的内容找到)并且会误导人们,所以我觉得我必须写这个。
另外,看看 jQuery 和原生浏览器选择器函数之间的时间差异。在 jQuery 1.2.6 中,$('.myForm')
比 getElementsByClassName
慢 300 倍,而在 jQuery 1.6 中 仅 大约 20 倍较慢,但仍比$('form.myForm')
快(与过时的答案相反)。
注意:结果是使用 Firefox 4 获得的(与 Chrome 的结果相似)。在 Opera 10 中,使用标签名称进行查询仅稍快一些,但 Opera 还支持更快的原生 getElementsByClassName
。
测试代码: http://jsbin.com/ijeku5
【讨论】:
【参考方案3】:第一个选择器应该更快,因为 jQuery 可以使用内置函数“getElementsByTagName”来减少它需要过滤的元素数量。第二个必须获取 DOM 中的所有元素并检查它们的类。
【讨论】:
【参考方案4】:试试slickspeed,您可以在其中看到选择器在包括 jquery 在内的多个 js 库中的粗略速度。
【讨论】:
很酷的网站! jQuery 赢了!但是,它不会测试 .className vs tagName.className :(【参考方案5】:form.myForm IMO 要快得多,因为它只需要查看一组子集/过滤的元素,而无需遍历整个文档。
【讨论】:
【参考方案6】:第一个示例在与上下文一起使用时会快很多。第二个例子也跑得更快,但不是很多。我扩展了您的示例以与上下文进行比较:
http://jsbin.com/uluwe
【讨论】:
【参考方案7】:enobrev,有趣。 我刚刚运行了您的示例,但使用的是 jquery 1.3 beta 2 here
结果....(括号内为 1.2.6 速度)
// With 100 non-form elements and Context:
$('.myForm', '#someContainer') : 4063ms (3707ms)
$('form.myForm', '#someContainer') : 6045ms (4644ms)
// With 100 non-form elements:
$('.myForm') : 3954ms (25086ms)
$('form.myForm') : 8802ms (4057ms)
// Without any other elements with Context:
$('.myForm', '#someContainer') : 4137ms (3594ms)
$('form.myForm', '#someContainer') : 6627ms (4341ms)
// Without any other elements:
$('.myForm') : 4278ms (7303ms)
$('form.myForm') : 8353ms (4033ms)
【讨论】:
哇,忘记 1.3 的上下文!!此外,这对于第二次测试(版本之间)有很大的不同。看起来 jquery 为 form.myForm 失去了一点速度,但 .myForm 的巨大收益可能会产生更大的整体差异。【参考方案8】:来吧,伙计们?你疯了吗?选择元素最快速的方式是最短的方式:
$('.myForm') 比 $('form.myform') 快得多,因为第二个变体必须进行额外检查以确保元素具有指定的 tagName。可能新的 jquery 1.3 会改变这个东西,但是在最新的稳定版本上,指定 tagName 也是错误的。你应该read here。
我想我在某处读到 MooTools 以这种方式更快。嗯..也许在 Moo 中,不知道,但在 jQuery 中这是最快的方式。
看看这个分析器:
(big pic)
第一个只有 ID,第二个是 form#ID(在我的博客页面上测试过)并且对于类选择器的工作方式完全相同。
【讨论】:
按标签名搜索元素比按类名搜索元素要快。 form.myForm 意味着您只需要搜索较小的元素子集。如果您只有几个元素,那么您将进行两次搜索,它可能会更慢,但在现实生活中 form.myForm 会胜出。 查看分析器结果(或进行您自己的测试)然后告诉我。此外,即使是约翰·雷西格也证实了这一点;) 另外,测试是在现实生活中进行的,而不是在测试站点上进行的。您甚至可以在这里尝试,以确保我说的是实话:) 但是您使用的是 id 选择器,所以当然如果您使用 tagName 进行 rpefix,它会更慢,因为 lib 无法使用 getElementById!!! 检查并更改您的测试以使用 .class 选择器。你会看到区别以上是关于在 jQuery 中查找元素的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章