高效的DOM选择技巧 - 选择属性是否太慢了?

3
我正在使用一个脚本,使所有在不支持该功能的浏览器中具有占位符的输入框。在该脚本中,我使用了:
$('input[placeholder]').each(function() {

选择所有要操作的元素。

我在想,这样做可能会比较慢,因为它不是一个非常具体的选择器,比如:

$('#input').each(function() {

我知道有一种方式可以更快地选择(但我不想分别指定所有id)。

您是否建议为所有具有占位符属性的输入添加类,例如:

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

为了让选择更快(我认为按类选择比按属性选择更快),但这会滥用css类的目的,只是用来进行样式设置,而且会填充DOM。
您有任何建议或技巧来改进这些任务吗?

哦,太酷了,我不知道这个。看起来按类选择确实更快。 - Björn
4个回答

3

我已经为比较选择器 input[placeholder], .hasPlaceholderinput 创建了一个 JSPerf,并使用 .filter() 进行了测试。

现在我们有了一些数据可以思考,让我们谈谈为什么你想知道这个。

你何时会搜索 'input[placeholder]'?希望只有一次。如果您在现代浏览器中执行这两个选择器之一,它们将非常快速(该数字是每秒操作次数....)。但是,如果您知道您仅在不支持占位符的浏览器上运行此选择器,则在列出的三种方法中,.hasPlacehoder 在 IE 6 中实际上是最慢的,自定义过滤器则胜出。您需要尝试在实际受到此代码影响的浏览器中测试性能。

请随意添加自己的选择器,或者更好的是将页面更接近您的确切HTML,并请求一些浏览器测试!

编辑:我在新的性能比赛中添加了input.hasPlaceholder...


+1 我不仅不知道JSPerf的存在,而且结果令人惊讶!(对我来说,使用过滤器比使用input[placeholder]快两倍) - Justin
@Kragen - $('input') 会被优化为 getElementsByTagName,然后通过过滤函数快速运行。在不支持 querySelectorAll 的浏览器中,这可能是最快的方法。 - gnarf
1
哇,实际的性能分析?谁会想到呢?这是一个很棒的测试,结果真是令人惊讶!我真的以为元素选择器比类选择器更快。真是令人困惑。 - Josh Smeaton

2

除非你有一个庞大的DOM,否则我认为性能差异不应该真正产生影响。像你说的那样,为了“优化”而设置大量类名会破坏文档的逻辑结构。

如果没有提供上下文,按类选择仍然会导致整个DOM被遍历。选择元素也是如此。在这里使用占位符类绝对不是答案。你想要做的是找到所有具有特定属性的输入元素 - 你正在使用正确的选择器来实现这个目的。


0

你可以给你的表单一个ID,然后使用$("#theForm input[placeholder]"),这样可以减少选择器需要考虑的元素数量。


是的,但我有很多表单,不想逐一指定。 - Björn
在这种情况下,我猜你没有获胜。选择一些“input”的限定符至少应该使用document.getElementsByTagName或类似的东西。因此,如果您认为检查类更快,则可以使用$("input.iHaveaPlaceholder")。 - araqnid
我很好奇比较 $("form input[placeholder]") 和 $("input[placeholder]")。我们都知道输入框应该在表单中,但我猜一个孤立的输入框也会匹配,证明引擎正在查看整个DOM。缩小到表单元素应该会稍微提高性能。 - Capsule
1
CSS选择器是从右到左应用的(http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/)。虽然jQuery可能会有所不同,但如果它使用浏览器的本机`querySelector`函数,则实际上会匹配所有`input[placeholder]`,然后过滤掉不是`#theForm`的后代元素。 - ide
1
我刚刚发现了这个测试网站。如果测试设置正确,我不认为它会更快。http://jsperf.com/attr-selector/2 - Björn
@Marcel - 你说的一半对了 --- 在Chrome 9中几乎没有区别...那IE6或者一些运行缓慢的浏览器呢?你可能会感到惊讶...不要太关注最快引擎的速度...很多东西都被优化了,而且Chrome有querySelectorAll - gnarf

0

它不慢(你测试过还是只是猜测?)。但如果可以,使用类。


有趣的悖论式答案;-) - Capsule
不是吗? :) 不,我的意思是我打赌他没有任何性能问题,他只是毫无理由地担心。但是类更快,这是事实。 - gblazex

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