[英]Comparing the performance of $(“#foo .bar”) and $(“.bar”, “#foo”)
getById.getByClassName
与qSA
比较! 如果我们想要选择ID为"foo"
的元素内的"bar"
类的所有元素,我们可以这样写:
$( '#foo .bar' )
或这个:
$( '.bar', '#foo' )
当然还有其他方法可以实现这一点,但是为了这个问题,我们只比较这两种方法。
那么,上述哪种方法表现更好? (这需要更少的时间来执行?)
我写了这个性能测试:
(function() {
var i;
console.time('test1');
for( i = 0; i < 100; i++ ) {
$('#question-mini-list .tags');
}
console.timeEnd('test1');
console.time('test2');
for( i = 0; i < 100; i++ ) {
$('.tags', '#question-mini-list');
}
console.timeEnd('test2');
})();
您必须在Stack Overflow开始页面的控制台内执行它。 我的结果是:
火狐:
test1:~90ms
test2:~18ms
铬:
test1:~65ms
test2:~30ms
歌剧:
test1:~50ms
test2:~100ms
所以在Firefox和Chrome中,第二种方法的速度要快很多倍 - 就像我预期的那样。 然而,在Opera中,情况正好相反。 我想知道这里发生了什么。
你可以在你的机器上运行测试并解释为什么Opera的表现不同吗?
我写了这个测试,以调查Opera的qSA是否真的超级快。 事实证明,它是。
(function() {
var i, limit = 5000, test1 = 'test1', test2 = 'test2';
console.time( test1 );
for( i = 0; i < limit; i += 1 ) {
document.getElementById( 'question-mini-list' ).getElementsByClassName( 'tags' );
}
console.timeEnd( test1 );
console.time( test2 );
for( i = 0; i < limit; i += 1 ) {
document.querySelectorAll( '#question-mini-list .tags' );
}
console.timeEnd( test2 );
})();
同样,您必须在Stack Overflow开始页面的控制台中运行此代码。 我使用了针对IE9的Firebug Lite书签(因为该浏览器没有实现console.time
)。
所以,我比较了这个方法:
document.getelementById( 'A' ).getElementsByClassName( 'B' );
这种方法:
document.querySelectorAll( '#A .B' );
我在每个浏览器中连续五次执行上面的脚本。 算术手段是:
(所有数字均以毫秒为单位。)
因此,第一种方法的性能在测试的浏览器中几乎相同(16-36ms)。 然而,虽然qSA与第一种方法相比要慢得多,但在Opera中它实际上更快!
所以,qSA优化是可能的,我想知道其他浏览器在等什么...
如果浏览器支持querySelectorAll
,并且传递了一个有效的选择器(没有自定义的非CSS选择器),jQuery / Sizzle将避免使用基于JavaScript的Sizzle引擎。
这意味着您最终要比较querySelectorAll
实现,假设您正在测试支持它的浏览器。
还有jQuery或Sizzle使用的其他优化,因此在不同浏览器中比较不同类型的DOM选择时,这很棘手。
Opera的性能结果的原因似乎是他们有一个非常高度优化的querySelectorAll
实现。 与较旧的方法(如getElementsByTagName
相比, qSA
是一种相对较新的方法,在某些浏览器中并没有得到优化。
最终获胜者是....
test 3 $('#question-mini-list').find('.tags');
您建议的两种方法不相同。
测试1 :Sizzle从右到左解析(不要求它在页面上搜索任何元素,然后限制为ID)。
测试2 :使用字符串作为上下文通常没有用,使用元素作为上下文。
测试3 :查找具有id的元素非常快。 一旦你在那里,轻松地专注于给定类的项目。
作为参考,这速度提高了30倍:
document.getElementById("foo").getElementsByClassName("bar");
请参阅jsPerf: http ://jsperf.com/jquery-selector-variations/3。 这需要一个垫片才能在旧版IE中使用。
虽然jQuery非常有用,但如果速度是最大的,那么它并不总是最适合这项工作的工具。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.