繁体   English   中英

比较$(“#foo .bar”)和$(“。bar”,“#foo”)的性能

[英]Comparing the performance of $(“#foo .bar”) and $(“.bar”, “#foo”)

向下滚动以获取getById.getByClassNameqSA比较!


如果我们想要选择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');

  • test1:25ms
  • test2:19ms
  • test3:10ms

您建议的两种方法不相同。

测试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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM