在 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 个&lt;p&gt; 标记和 4 个&lt;form&gt;s 开始,运行两个不同的测试,删除&lt;p&gt; 标记并再次运行测试。奇怪的是,当使用这种技术时,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')getElementsByClassName300 倍,而在 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 中查找元素的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

在 jQuery 中构建 html 元素的最清晰方法

在 Go 中访问二维数组中的相邻元素的最有效方法是啥?

从长(且合理)稀疏向量中选择随机元素的最有效方法是啥?

在 React 中迭代数据数组时呈现 JSX 元素的最有效方法

从数组列表中删除元素的最有效方法? [关闭]

删除列表中前 N 个元素的最有效方法?