Javascript 为什么$(div#id)比$(id)慢?
除非我的测试出了什么问题,否则当我在Chrome上运行这个JSFIDLE时,Javascript 为什么$(div#id)比$(id)慢?,javascript,jquery,performance,google-chrome,Javascript,Jquery,Performance,Google Chrome,除非我的测试出了什么问题,否则当我在Chrome上运行这个JSFIDLE时,$(“#id”)选择器大约需要11ms,而$(div#id)选择器大约需要56ms $(document).ready(function(){ startTime = new Date().getTime(); for (i = 0; i < 10000; i++) { s = $("#idC12"); } $("#idResults")
$(“#id”)
选择器大约需要11ms,而$(div#id)
选择器大约需要56ms
$(document).ready(function(){
startTime = new Date().getTime();
for (i = 0; i < 10000; i++)
{
s = $("#idC12");
}
$("#idResults").html("c12 by id only time: "+elapsedMilliseconds(startTime));
startTime = new Date().getTime();
for (i = 0; i < 10000; i++)
{
s = $("div#idC12");
}
$("#classResults").html("c12 by tagname#id: "+elapsedMilliseconds(startTime));
});
function elapsedMilliseconds(startTime)
{
var n = new Date();
var s = n.getTime();
var diff = s - startTime;
return diff;
}
$(文档).ready(函数(){
startTime=新日期().getTime();
对于(i=0;i<10000;i++)
{
s=$(“#idC12”);
}
$(“#idResults”).html(“仅id时间的c12:+elapsedmillyses(startTime));
startTime=新日期().getTime();
对于(i=0;i<10000;i++)
{
s=$(“div#idC12”);
}
$(“#classResults”).html(“c12按标记名#id:+elapsedmillesons(startTime));
});
函数elapsedMilliseconds(开始时间)
{
var n=新日期();
var s=n.getTime();
var diff=s-开始时间;
返回差;
}
这是因为$(“#id”)
在内部使用本机函数,该函数使用从id到具有此id的(唯一)元素的映射链接
以下是jQuery源代码中的相关代码:
// Easily-parseable/retrievable ID or TAG or CLASS selectors
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/
...
// Speed-up: Sizzle("#ID")
if ( (m = match[1]) ) {
if ( nodeType === 9 ) {
elem = context.getElementById( m );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document #6963
if ( elem && elem.parentNode ) {
// Handle the case where IE, Opera, and Webkit return items
// by name instead of ID
if ( elem.id === m ) {
results.push( elem );
return results;
}
} else {
return results;
}
} else {
// Context is not a document
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
contains( context, elem ) && elem.id === m ) {
results.push( elem );
return results;
}
}
你会注意到:
- 当正则表达式检测到
表单时使用它#someId
- 任何提供的上下文都只会添加一个测试,并不能加快测试速度
请注意,在jQuery之外,当定义CSS规则或使用
document.querySelector
时,此规则仍然适用:当您知道id时,没有什么比使用document.getElementById
更快的了(除了缓存的元素…。我在源代码中已经有一段时间了,但我知道一些id选择器过去是由document.getElementById()
处理的,而更复杂的选择器(例如,标记名#一些id
)必须通过嘶嘶声,最终通过document.queryselectoral
$('div#id'))
速度较慢,因为它不直接映射到本机的getElementById()
方法。使用div#id时,首先选择所有div
当您使用#id时,它会直接进入id表。准备好,设置好,开始!You win:)要添加到这一点上,$(div#id)必须在div上运行一个额外的选择器。我必须查看sizzle引擎,看看是否首先查找并检查$(#id)以确保div性,但我想象ir首先运行querySelectAll(div),然后检查id。有时我忘记了为什么使用jQuery,然后我看到了其中的一些评论并记住了原因。这是一个黑暗、黑暗的世界……而且,
id
属性在HTML文档中应该是唯一的,如果不是,那么$(“#id”)
将只返回与该id
匹配的第一个元素,就像getElementById()
一样。但是,$(“*#id”)
将返回所有满足条件的内容。它是否仍然是一个从右到左的实现呢?@jmar777我不这么认为。我认为CSS就是这样工作的,而不是jQuery的选择过程。我发誓我刚读到一些关于这个的东西。也许我错了。我去找找it@jmar777或者,这可能是一种特殊情况,jQuery在字符串中的任何位置查找#
,然后将调用直接映射到getElementById
,而不是从右向左传递给querySelectorAll
?在获取容器中的特定项目之前,是否需要在左侧获取容器…在右侧?可能是在使用组合选择器时,即使用空格/逗号运算符。@Ian我认为线程与#foo.bar
样式选择器更相关,然后是.foo#bar
。并且提供的源中的正则表达式与标记名id选择器不匹配。但是,您可能在从右到左的范围内是正确的,仅适用于“组”级别。我想我可能需要在这一点上进一步挖掘…除了下面非常好的答案,我想说,因为你应该在页面上有唯一的Id,没有必要像div#Id那样具体。。。