【发布时间】:2012-01-25 19:01:19
【问题描述】:
向下滚动查看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 起始页上的控制台中执行它。我的结果是:
火狐:
测试1:~90ms
测试2:~18ms
铬:
测试1:~65ms
测试2:~30ms
歌剧:
测试1:~50ms
测试2:~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优化是可能的,不知道其他浏览器在等什么……
【问题讨论】:
-
test1: 73ms,test2: 11ms。 Opera 是一个奇怪的浏览器,我不知道它为什么会滞后。 -
@Blender 请增加循环限制。我的笔记本电脑真的很慢,所以我选择了 100。尝试 1000。(小于
4ms的结果不可靠...) -
您是否考虑过包含
document.getElementById('foo').getElementsByClassName('bar')以确保完整性? -
不同的实现有不同的优化。要做什么? ;)
-
对于测试jsperf.com会是更好的选择。
标签: javascript jquery performance browser