jQueryで子孫要素を選択する最速の方法は何ですか?


101

私の知る限り、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();

これを自分で調査できるプロファイリングについては詳しくないので、あなたの意見を聞きたいと思います。

PSこれはこの質問の重複の可能性があることを理解していますが、すべての方法を網羅しているわけではありません。


また、@ spinon-それは直接の子供だけのためですか?CSS仕様では、「要素Eの子であるすべてのF要素に一致する」と記載されています。
マルコ

7
あなたは本当にどれが速いか心配する必要はありません(本当に大きなdom操作をしているのでなければ)... jQueryは驚くほど速くなるように構築されました...
Reigel

私は2MBのHTMLファイルを持っています。方法や理由は質問しないでください:)
Marko

1
はい。第1レベルの子孫のみ。
スピノン

もう1つの方法があります。$( "#parent .child")。show(); これは方法#2と同じです。:)
カイ

回答:


95

メソッド1メソッド2は同じですが、唯一の違いは、メソッド1は渡されたスコープを解析し、それをへの呼び出しに変換する必要があること$parent.find(".child").show();です。

方法4方法5はどちらも、セレクターを解析してから$('#parent').children().filter('.child')$('#parent').filter('.child')それぞれを呼び出すだけです。

したがって、メソッド3は最短の作業量で済み、最も直接的なメソッドを使用して第1レベルの子を取得するため、常に最速になります。

ここでアヌラグの改訂された速度テストに基づく:http : //jsfiddle.net/QLV9y/1/

速度テスト:(多いほど良い)

上のクロム、方法3は、最高の、メソッド1/2、その後4/5であります

ここに画像の説明を入力してください

のFirefox、方法3は、まだ最良の方法1/2で、その後4/5

ここに画像の説明を入力してください

オペラ、方法3は、まだ最良の方法4/5で、その後1/2

ここに画像の説明を入力してください

上のIE 8、低速の全体的な他のブラウザに比べながら、それはまだ方法3、1,2,4,5順序に従います。

ここに画像の説明を入力してください

全体として、メソッド3は、直接呼び出されるため、使用するのに非常に最適なメソッドであり、メソッド1/2のように複数レベルの子要素をトラバースする必要はなく、メソッド4/5のように解析する必要もありません。

ただし、これらのいくつかでは、メソッド5が第1レベルの子ではなくすべての子を調べるときに、リンゴをオレンジと比較していることに注意してください。


同一とは、両方が同じロジックを使用して検索することを意味しますか?
マルコ

4
方法1と2は同じだということですか?
グッファ

@Aaronに感謝-他の人の考えを見てみたい。みんなが同意すれば、あなたの答えを受け入れる。乾杯:)
マルコ

@JP、つまり、スコープがそれに変換されるために渡されていることを認識するのに余分な時間がかかる必要があることを意味します $parent.find(".child");コマンドです。
アーロンハルン

2
@Aaron @Marko-ルートノードを常にコンテキストとして使用しており、ドキュメントがかなり大きいため、テストは少し歪んでいる可能性があります。それにもかかわらず、ほとんどの実行では、1と2が互いに20 ops / sec以内で並ぶことがわかります。1と2と比較すると、4は約100〜200オペレーション遅く、5は約400オペレーション遅いです。これは、子供だけでなくすべての子孫を通過するため理解できます。チャート-tinyurl.com/25p4dhq
Anurag

13

方法1

jQueryを使用して短く短くすることはできません。この呼び出しは$(context).find(selector)(最適化のためにメソッド2に)直接到達し、次にが呼び出されますgetElementById

方法2

同じことをしていますが、不要な内部関数呼び出しはありません。

方法3

を使用して children()はよりも高速ですfind()が、もちろん、children()ルート要素の直接の子のみを検索しますが、find()再帰的にトップダウンですべての子要素(サブ子要素を含む)まで検索します

方法4

このようなセレクターを使用すると、遅くなるはずです。以来sizzle動作します(jQueryのからセレクタエンジンである)右から左に、それはすべてのクラスと一致します.child彼らはID「親」からの直接の子であれば、それは見た目の前に最初に。

方法5

あなたが正しく述べたように、この呼び出しは関数$(context).find(selector)内のいくつかの最適化のために呼び出しも作成します。jQuerysizzle engine


2
あなたは変数$ parent = $( "#parent")について話していませんか?要素にクラスがある場合にメソッド1がgetElementByIdをどのように使用できるかがわかりませんか?
マルコ

1
私は、ドキュメントは言う、方法1で、同意したかったけどInternally, selector context is implemented with the .find() method、私はあなたが:) OPのラベルに混乱してしまったけど、願いアップデートを
Reigel

@Reigel:修正されました。@Marko:解析#parentはIDを表し、それがクラスの場合、getElementById明らかに使用しません。
jAndy

10

古い投稿ですので、時間とともに物事が変わります。私はこれまでのところ、最後のブラウザーバージョンでいくつかのテストを行いましたが、誤解を避けるためにここに投稿しています。

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

したがって、100,000回の反復で、次のようになります。

JS jQueryセレクター統計

(フォーマットの目的でimgとして追加しました。)

コードスニペットを自分で実行してテストできます;)


ああ!それから.find()素晴らしい仕事をするように見えます。使い続ける。:)
Andrew Surdu 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.