getById.getByClassName
与qSA
比较!如果我们想要选择ID为"bar"
的元素内的"foo"
类的所有元素,我们可以这样写:
$( '#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 start-page 的控制台内执行它。我的结果是:
火狐:
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优化是可能的,我想知道其他浏览器在等什么......
答案 0 :(得分:3)
querySelectorAll
,并且传递了有效的选择器(没有自定义的非CSS选择器),jQuery / Sizzle将避免使用基于JavaScript的Sizzle引擎。
这意味着您最终要比较querySelectorAll
的实现,假设您正在测试支持它的浏览器。
还有jQuery或Sizzle使用的其他优化,因此在不同浏览器中比较不同类型的DOM选择时,这很棘手。
Opera的性能结果似乎是因为它们具有非常高度优化的querySelectorAll
实现。 qSA
是一种相对较新的方法,与getElementsByTagName
等旧方法相比,在某些浏览器中并未得到优化。
答案 1 :(得分:1)
获胜者是......
测试3 $('#question-mini-list').find('.tags');
您建议的两种方法不相同。
测试1 :Sizzle从右到左解析(不要求它在页面上搜索任何元素,然后限制为ID)。
测试2 :使用字符串作为上下文通常没有用,请使用元素作为上下文。
测试3 :查找带有id的元素非常快。一旦你在那里,就可以轻松地专注于某个特定类的项目。
答案 2 :(得分:1)
作为参考,速度提高了30倍:
document.getElementById("foo").getElementsByClassName("bar");
参见jsPerf:http://jsperf.com/jquery-selector-variations/3。这需要垫片才能在旧版IE中使用。
虽然jQuery非常有用,但如果速度最快,那么它并不总是最适合这项工作的工具。