61

たとえば、最初のコードは完全な検索を2回実行しますか、それともDOMの変更が発生しなかった場合に結果をキャッシュするのに十分賢いですか?

if ($("#navbar .heading").text() > "") {
  $("#navbar .heading").hide();
}

var $heading = $("#navbar .heading");

if ($heading.text() > "") {
  $heading.hide();
}

セレクターがもっと複​​雑な場合、それは重要なヒットだと想像できます。

4

14 に答える 14

30

常に選択内容をキャッシュしてください!

$( selector )常に同じセレクターで何度も呼び出すのはもったいないです。

または、ほとんどの場合... jQuery オブジェクトのキャッシュされたコピーは、変更されていることが予想される場合や一度だけ必要な場合を除いて、通常はローカル変数に保持する必要があります。

var element = $("#someid");

element.click( function() {

  // no need to re-select #someid since we cached it
  element.hide(); 
});
于 2012-04-15T04:15:19.677 に答える
16

jQuery はそうではありませんが、式内の変数に代入して、後続の式でそれらを再利用する可能性があります。だから、あなたの例をキャッシュ化...

if ((cached = $("#navbar .heading")).text() > "") {
  cached.hide();
}

欠点は、コードがややこしくなり、理解しにくくなることです。

于 2008-11-15T00:57:52.267 に答える
14

それは「できるか」という問題ではなく、「できるか」という問題であり、いや、できません。クエリが最後に実行されてから、一致する要素を DOM に追加した可能性があります。これにより、キャッシュされた結果が古くなり、jQuery には、クエリを再度実行する以外に (賢明な) 通知方法がありません。

例えば:

$('#someid .someclass').show();
$('#someid').append('<div class="someclass">New!</div>');
$('#someid .someclass').hide();

この例では、クエリのキャッシュがあった場合、新しく追加された要素は非表示になりません。以前に表示された要素のみが非表示になります。

于 2008-11-16T11:26:17.427 に答える
13

この問題を解決する方法を実行しました:

var cache = {};

function $$(s)
{
    if (cache.hasOwnProperty(s))
    {
        return $(cache[s]);
    }

    var e = $(s);

    if(e.length > 0)
    {
        return $(cache[s] = e);
    }

}

そして、それは次のように機能します:

$$('div').each(function(){ ... });

この簡単なチェックに基づいて、結果は私が知る限り正確です。

console.log($$('#forms .col.r')[0] === $('#forms .col.r')[0]);

注意: MooTools の実装や$$表記法を使用するその他のライブラリが壊れます。

于 2011-10-14T13:24:21.547 に答える
9

私はそうは思わない (確かに確認するために現時点で 3.5 千行の JavaScript を読む気はありませんが)。

ただし、あなたがしていることは複数のセレクターを必要としません - これはうまくいくはずです:

$("#navbar .heading:not(:empty)").hide();
于 2008-11-15T00:25:20.333 に答える
6

$$アプローチと同様に、記憶パターンを使用してグローバルをクリーンに保ち、$$( "。class"、 "#context"などの2番目のコンテキストパラメーターも考慮する)関数を作成しました。 )。これは、$$が返された後に発生する連鎖関数find()を使用する場合に必要です。したがって、最初にコンテキストオブジェクトをキャッシュしない限り、単独でキャッシュされることはありません。また、ブールパラメータを最後に追加して(コンテキストを使用するかどうかに応じて2番目または3番目のパラメータ)、強制的にDOMに戻します。

コード:

function $$(a, b, c){
    var key;
    if(c){
        key = a + "," + b;
        if(!this.hasOwnProperty(key) || c){
            this[key] = $(a, b);
        }        
    }
    else if(b){
        if(typeof b == "boolean"){  
            key = a;  
            if(!this.hasOwnProperty(key) || b){
                this[key] = $(a);
            }
        }
        else{
            key = a + "," + b;
            this[key] = $(a, b);   
        }            
    }
    else{
        key = a;
        if(!this.hasOwnProperty(key)){
            this[key] = $(a);
        } 
    }
    return this[key]; 
}

使用法:

<div class="test">a</div>
<div id="container">
    <div class="test">b</div>
</div>​

<script>
  $$(".test").append("1"); //default behavior
  $$(".test", "#container").append("2"); //contextual 
  $$(".test", "#container").append("3"); //uses cache
  $$(".test", "#container", true).append("4"); //forces back to the dome
​
</script>
于 2012-07-20T17:10:49.530 に答える
4

jqueryがセレクターのキャッシュを行うとは思わず、代わりにその下にあるxpath/javascriptに依存してそれを処理します。そうは言っても、セレクターで利用できる多くの最適化があります。いくつかの基本をカバーするいくつかの記事を次に示します。

于 2008-11-15T00:23:29.887 に答える
4

この $$() は正常に動作します - いずれにせよ、決して未定義ではない有効な jQuery オブジェクトを返す必要があります。

注意してください!動的に変化する可能性のあるセレクターを使用する必要があります/できません。セレクターに一致するノードを追加するか、疑似クラスを使用します。

function $$(selector) {
  return cache.hasOwnProperty(selector) 
    ? cache[selector] 
    : cache[selector] = $(selector); 
};

もちろん、$$ は任意の関数名にすることができます。

于 2012-08-23T14:00:56.357 に答える
2

jsPerf は今日ダウンしていますが、この記事では、jQuery セレクターをキャッシュすることによるパフォーマンスの向上は最小限であることを示唆しています。

ここに画像の説明を入力

これは単にブラウザのキャッシングが原因である可能性があります。テストされたセレクターは単一の ID のみでした。より複雑なセレクターと異なるページ構造については、さらにテストを行う必要があります...

于 2015-07-02T09:16:22.920 に答える
2

John Resig は、jQuery Camp 2008 での Jquery Internals の講演で、DOM が変更されたときに発生するイベントをサポートするブラウザーについて言及しています。このような場合、セレクターの結果をキャッシュすることができます。

于 2011-03-20T10:12:54.343 に答える
1

$.selectorCache() は便利です:

https://gist.github.com/jduhls/ceb7c5fdf2ae1fd2d613e1bab160e296

要点の埋め込み:

<script src="https://gist.github.com/jduhls/ceb7c5fdf2ae1fd2d613e1bab160e296.js"></script>

于 2016-05-24T17:25:06.730 に答える
1

jQuery Sizzleは、DOM 要素を見つけるために、セレクターから作成された最近の関数を自動的にキャッシュします。ただし、要素自体はキャッシュされません。

さらに、Sizzle は最近コンパイルされた関数のキャッシュを保持します。キャッシュには最大サイズ (調整可能ですがデフォルトがあります) があるため、多くの異なるセレクターを使用してもメモリ不足エラーが発生しません。

于 2012-12-03T23:14:52.780 に答える