Javascript jQuery上下文减慢了搜索速度
可能重复:Javascript jQuery上下文减慢了搜索速度,javascript,jquery,performance,jquery-selectors,jquery-context,Javascript,Jquery,Performance,Jquery Selectors,Jquery Context,可能重复: 上面说 默认情况下,选择器在DOM中执行搜索 在文档根目录下。但是,可以为其提供另一个上下文 通过使用$()函数的可选第二个参数进行搜索 基于此,我的理解是,使用作为第二个参数传入的上下文的选择应该比没有传入的上下文的相同选择更快。然而,我运行了一些测试,似乎情况并非如此,或者至少并非总是如此 为了详细说明,我最初想看看一次搜索多个元素($(“div1,#div2”))是否比单独搜索两个元素更快($(“div1”)$(“div2”))。然后,我决定用上下文测试它,而不去看上下文的速
上面说 默认情况下,选择器在DOM中执行搜索 在文档根目录下。但是,可以为其提供另一个上下文 通过使用$()函数的可选第二个参数进行搜索 基于此,我的理解是,使用作为第二个参数传入的
上下文的选择应该比没有传入的上下文的相同选择更快。然而,我运行了一些测试,似乎情况并非如此,或者至少并非总是如此
为了详细说明,我最初想看看一次搜索多个元素($(“div1,#div2”)
)是否比单独搜索两个元素更快($(“div1”)$(“div2”)
)。然后,我决定用上下文
测试它,而不去看上下文
的速度有多快,但当发现上下文
似乎在减慢它时,我感到惊讶
例如,给定以下基本HTML标记
<div id="testCnt">
<div id="Div0"></div>
<div id="Div1"></div>
<div id="Div2"></div>
<div id="Div3"></div>
<div id="Div4"></div>
<div id="Div5"></div>
<div id="Div6"></div>
<div id="Div7"></div>
<div id="Div8"></div>
<div id="Div9"></div>
</div>
以及以下JavaScript(jQuery1.8.2,并使用FireBug进行测试)
$(函数(){
var$dvCnt=$(“#testCnt”);
var-dvCnt=$dvCnt[0];
console.time(“没有缓存的个人”);
对于(变量i=0;i<10000;i++){
$('#Div0')。文本('Test');
$('#Div1')。文本('Test');
$('#Div2')。文本('Test');
$('#Div3')。文本('Test');
$('#Div4')。文本('Test');
$('#Div5')。文本('Test');
$('#Div6')。文本('Test');
$('#Div7')。文本('Test');
$('#Div8')。文本('Test');
$('#Div9')。文本('Test');
}
console.timeEnd(“没有缓存的个人”);
console.time($cache的个人);
对于(变量i=0;i<10000;i++){
$('#Div0',$dvCnt).text('Test');
$('#Div1',$dvCnt).text('Test');
$('#Div2',$dvCnt).text('Test');
$('#Div3',$dvCnt).text('Test');
$('#Div4',$dvCnt).text('Test');
$('#Div5',$dvCnt).text('Test');
$('#Div6',$dvCnt).text('Test');
$('#Div7',$dvCnt).text('Test');
$('#Div8',$dvCnt).text('Test');
$('#Div9',$dvCnt).text('Test');
}
console.timeEnd('Individual with$cache');
console.time(“具有DOM缓存的个人”);
对于(变量i=0;i<10000;i++){
$('#Div0',dvCnt).text('Test');
$('#Div1',dvCnt).text('Test');
$('#Div2',dvCnt).text('Test');
$('#Div3',dvCnt).text('Test');
$('#Div4',dvCnt).text('Test');
$('#Div5',dvCnt).text('Test');
$('#Div6',dvCnt).text('Test');
$('#Div7',dvCnt).text('Test');
$('#Div8',dvCnt).text('Test');
$('#Div9',dvCnt).text('Test');
}
timeEnd('带有DOM缓存的个人');
console.time('Multiple without cache');
对于(变量i=0;i<10000;i++){
$(“#Div0,#Div1,#Div2,#Div3,#Div4,#Div5,#Div6,#Div7,#Div8,#Div9”)。文本('Test');
}
console.timeEnd('Multiple without cache');
console.time('Multiple with$cache');
对于(变量i=0;i<10000;i++){
$(“#Div0,#Div1,#Div2,#Div3,#Div4,#Div5,#Div6,#Div7,#Div8,#Div9',$dvCnt)。文本('Test');
}
console.timeEnd('Multiple with$cache');
time('Multiple with DOM cache');
对于(变量i=0;i<10000;i++){
$(“#Div0,#Div1,#Div2,#Div3,#Div4,#Div5,#Div6,#Div7,#Div8,#Div9”,dvCnt)。文本('Test');
}
timeEnd('Multiple with DOM cache');
});
这里有一个
我得到了如下结果
无缓存的个人:11490ms
具有$cache的个人:13315ms
具有DOM缓存的个人:14487ms
多个无缓存:7557ms
多个$cache:7824ms
具有DOM缓存的多个:8589ms
有人能解释一下发生了什么吗?具体来说,为什么传递jQuery上下文时搜索速度会减慢
编辑:
这里的大多数Anwser(以及)基本上都说,本例中的DOM太小,不能真正获得太多,或者通过ID
进行选择会很快。我理解这两点,我问题的重点是为什么上下文会减慢搜索速度,DOM的大小不应该对这一点产生影响,按ID搜索速度已经非常快这一事实也不应该造成影响
建议其速度较慢的原因是jQuery无法使用本机浏览器方法(getElementByID
),这对我来说似乎是有意义的,但为什么在一个选择中搜索多个元素会更快呢
无论如何,我将测试转储到一个添加cases以按类搜索的窗口中,并且再次惊讶地看到,这次使用缓存搜索多个类的速度是最快的。由于您选择的是按ID,jQuery(或sizzle,我忘了)将跳转到速度更快的文档。在本例中为getElementById()。使用类时,您可能会得到不同的结果,但即使如此,它也可能因浏览器而异
您可以使用类似于的东西使测试变得更容易。我可以想象,在很多情况下,使用上下文会降低测试速度,主要是因为jQuery会尝试在可能的情况下使用浏览器本机方法,而不是遍历整个dom。其中一个例子是使用document.getElementById
,如您的示例所示
为什么慢下来?
getElementById
仅存在于文档对象上-您无法在上下文元素上使用它-即element.getElementById
。因此,我的理论是,jQuery首先使用document.getElementById
执行id请求,然后,如果存在上下文集,则扫描每个元素的父元素,以确定它们是否作为
$(function () {
var $dvCnt = $('#testCnt');
var dvCnt = $dvCnt[0];
console.time('Individual without cache');
for (var i = 0; i < 10000; i++) {
$('#Div0').text('Test');
$('#Div1').text('Test');
$('#Div2').text('Test');
$('#Div3').text('Test');
$('#Div4').text('Test');
$('#Div5').text('Test');
$('#Div6').text('Test');
$('#Div7').text('Test');
$('#Div8').text('Test');
$('#Div9').text('Test');
}
console.timeEnd('Individual without cache');
console.time('Individual with $cache');
for (var i = 0; i < 10000; i++) {
$('#Div0', $dvCnt).text('Test');
$('#Div1', $dvCnt).text('Test');
$('#Div2', $dvCnt).text('Test');
$('#Div3', $dvCnt).text('Test');
$('#Div4', $dvCnt).text('Test');
$('#Div5', $dvCnt).text('Test');
$('#Div6', $dvCnt).text('Test');
$('#Div7', $dvCnt).text('Test');
$('#Div8', $dvCnt).text('Test');
$('#Div9', $dvCnt).text('Test');
}
console.timeEnd('Individual with $cache');
console.time('Individual with DOM cache');
for (var i = 0; i < 10000; i++) {
$('#Div0', dvCnt).text('Test');
$('#Div1', dvCnt).text('Test');
$('#Div2', dvCnt).text('Test');
$('#Div3', dvCnt).text('Test');
$('#Div4', dvCnt).text('Test');
$('#Div5', dvCnt).text('Test');
$('#Div6', dvCnt).text('Test');
$('#Div7', dvCnt).text('Test');
$('#Div8', dvCnt).text('Test');
$('#Div9', dvCnt).text('Test');
}
console.timeEnd('Individual with DOM cache');
console.time('Multiple without cache');
for (var i = 0; i < 10000; i++) {
$('#Div0,#Div1 ,#Div2 ,#Div3 ,#Div4 ,#Div5 ,#Div6, #Div7, #Div8, #Div9').text('Test');
}
console.timeEnd('Multiple without cache');
console.time('Multiple with $cache');
for (var i = 0; i < 10000; i++) {
$('#Div0,#Div1 ,#Div2 ,#Div3 ,#Div4 ,#Div5 ,#Div6, #Div7, #Div8, #Div9', $dvCnt).text('Test');
}
console.timeEnd('Multiple with $cache');
console.time('Multiple with DOM cache');
for (var i = 0; i < 10000; i++) {
$('#Div0,#Div1 ,#Div2 ,#Div3 ,#Div4 ,#Div5 ,#Div6, #Div7, #Div8, #Div9', dvCnt).text('Test');
}
console.timeEnd('Multiple with DOM cache');
});
$('.className');
$('.className .anotherClassName');
$('div', context);
$().pushStack( context[0].getElementsByTagName('div') );
$( context[0].getElementsByTagName('div') );
$('h2 > a');
$('h2 > a:eq(0)');
$('h2:eq(0) > a:eq(0)');
function (a,b){var c=typeof a=="string"?p(a,b):p.makeArray(a&&a.nodeType?
[a]:a),d=p.merge(this.get(),c);return this.pushStack(bh(c[0])||bh(d[0])?
d:p.unique(d))}
function (a,b,c){var d=p.merge(this.constructor(),a);return
d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector
+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")"),d}
$(document.getElementById('id'));
jQuery.byid = function(id){
return jQuery(document.getElementById(id))
};
$.byid('elementid');
$('.myClass', dvCnt).text('Test');
$(dvCnt).find('.myClass').text('Test');
var myDiv = $(dvCnt)
myDiv.find('.myClass1').text('Test');
myDiv.find('.myClass2').text('Test');