Каков самый быстрый способ выбора элементов-потомков в jQuery?

Насколько я знаю, существует несколько способов выбора дочерних элементов в 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. Я понимаю, что это возможный дубликат этого вопроса, но он не охватывает все методы.

Ответ 1

Метод 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 рассматривает всех детей, а не детей первого уровня.

Ответ 2

Метод 1

Невозможно сократить и ускорить использование jQuery. Этот вызов напрямую сбрасывается до $(context).find(selector) ( метода 2 из-за оптимизации), который, в свою очередь, вызывает getElementById.

Метод 2

Выполняет то же самое, но без лишних внутренних вызовов функций.

Метод 3

с помощью children() работает быстрее, чем при использовании find(), но, конечно, children() найдет только прямые дочерние элементы корневого элемента, тогда как find() будет искать рекурсивно сверху вниз ко всем дочерним элементам (включая дочерние элементы )

Метод 4

Использование селекторов, подобных этому, должно быть медленнее. Поскольку sizzle (который является механизмом выбора из jQuery) работает справа налево, он будет соответствовать всем классам .child сначала, прежде чем он посмотрит, являются ли они прямым потомком из id 'parent'.

Метод 5

Как вы правильно сказали, этот вызов также создаст вызов $(context).find(selector) из-за некоторой оптимизации в функции jQuery, иначе он может также пройти через (медленнее) sizzle engine.

Ответ 3

Как это старый пост, и все меняется со временем. Я провел несколько тестов в последних версиях браузеров, и я разместил их здесь, чтобы избежать недоразумений.

Используя jQuery 2.1 в браузерах, совместимых с HTML5 и CSS3, производительность изменяется.

Вот тестовый сценарий и результаты:

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);
}
<!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>