在jQuery中选择后代元素的最快方法是什么?

时间:2010-07-05 07:29:17

标签: jquery performance jquery-selectors profiling

据我所知,有很多方法可以在 jQuery 中选择子元素。

//Store parent in a variable  
var $parent = $("#parent");

方法1 (使用范围)

$(".child", $parent).show();

方法2 (find()方法)

$parent.find(".child").show();

方法3 (仅限直系儿童)

$parent.children(".child").show();

方法4 (通过CSS选择器) - @spinon建议

$("#parent > .child").show();

方法5 (与方法2 相同) - 根据@Kai

$("#parent .child").show();

我不熟悉能够自行调查的分析,所以我很想知道你要说些什么。

P.S。我理解这可能是this question的副本,但并不涵盖所有方法。

3 个答案:

答案 0 :(得分:95)

方法1 方法2 相同,唯一的区别是方法1 需要解析传递的范围并将其转换为致电$parent.find(".child").show();

方法4 方法5 都需要解析选择器,然后分别调用:$('#parent').children().filter('.child')$('#parent').filter('.child')

所以方法3 总是最快的,因为它需要做的工作量最少,并且使用最直接的方法来获得第一级别的孩子。

根据Anurag在此修订的速度测试:http://jsfiddle.net/QLV9y/1/

速度测试:(更多更好)

Chrome 上,方法3是最好的方法1/2然后是4/5

enter image description here

Firefox 上,方法3仍然是最好的方法1/2然后是4/5

enter image description here

Opera 上,方法3仍然是最好的方法4/5然后是1/2

enter image description here

IE 8 上,虽然总体上比其他浏览器慢,但仍然遵循方法3,1,2,4,5顺序。

enter image description here

总的来说,方法3 是最好的方法,因为它是直接调用的,它不需要遍历多个子元素级别,这与方法1/2不同,并且它不会需要像方法4/5一样进行解析

尽管如此,请记住,在其中一些中我们将苹果与橙子进行比较,因为方法5会查看所有孩子而不是第一级孩子。

答案 1 :(得分:13)

方法1

使用jQuery不能越来越短。此调用直接降至$(context).find(selector)方法2 ,由于优化),而这又调用了getElementById

方法2

正在做同样的事情,但没有一些不必要的内部函数调用。

方法3

使用children()比使用find()更快,但当然,children()只能查找根元素的直接子元素,而find()将自上而下搜索到所有儿童元素(包括子元素)

方法4

使用像这样的选择器必须更慢。由于sizzle(来自jQuery的选择器引擎)工作从右到左,因此它首先匹配所有类.child,然后才会查看它们是否是来自id的直接子项父”。

方法5

正如您所说的那样,由于$(context).find(selector)函数中的某些优化,此调用也会创建jQuery调用,否则它也可能会通过(较慢)sizzle engine

答案 2 :(得分:9)

因为它是一个老帖子,事情随着时间而变化。到目前为止,我对最后一个浏览器版本进行了一些测试,我在这里发布它是为了避免误解。

在兼容HTML5和CSS3的浏览器上使用jQuery 2.1,性能会发生变化。

以下是测试方案和结果:



function doTest(selectorCallback) {
    var iterations = 100000;

    // Record the starting time, in UTC milliseconds.
    var start = new Date().getTime();

    for (var i = 0; i < iterations; i++) {
        // Execute the selector. The result does not need to be used or assigned
        selectorCallback();
    }

    // Determine how many milliseconds elapsed and return
    return new Date().getTime() - start;
}

function start() {
    jQuery('#stats').html('Testing...');
    var results = '';

    results += "$('#parent .child'): " + doTest(function() { jQuery('#parent .child'); }) + "ms";
    results += "<br/>$('#parent > .child'): " + doTest(function() { jQuery('#parent > .child'); }) + "ms";
    results += "<br/>$('#parent').children('.child'): " + doTest(function() { jQuery('#parent').children('.child'); }) + "ms";
    results += "<br/>$('#parent').find('.child'): " + doTest(function() { jQuery('#parent').find('.child'); }) + "ms";
    $parent = jQuery('#parent');
    results += "<br/>$parent.find('.child'): " + doTest(function() { $parent.find('.child'); }) + "ms";

    jQuery('#stats').html(results);
}
&#13;
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9, chrome=1" />
    <title>HTML5 test</title>
    <script src="//code.jquery.com/jquery-2.1.1.js"></script>
</head>
<body>

<div id="stats"></div>
<button onclick="start()">Test</button>

<div>
    <div id="parent">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
    </div>
</div>

</body>
</html>
&#13;
&#13;
&#13;

因此,对于100 000次迭代,我得到:

JS jQuery selector stats

(我已将它们添加为img以用于格式化目的。)

您可以自行运行代码段进行测试;)