56

ここの人々は、次のコードのように、要素jQueryから作成されたオブジェクトをキャッシュすることをよく提案します。DOM

$('#container input').each(function() {
    $(this).addClass('fooClass');
    $(this).attr('data-bar', "bar");
    $(this).css('background-color', 'red');
});
  • jQuery オブジェクトをキャッシュすると、コードのパフォーマンスが本当に向上するのでしょうか?
  • DOM 要素を jQuery コンストラクターに渡すと、「舞台裏」で何が起こるでしょうか?
4

4 に答える 4

53

jQueryタグ情報に、次の警告が表示されます。

jQuery 関数 $() は高価です。繰り返し呼び出すのは非常に非効率的です。

ええと...これは、文字列セレクターにのみ当てはまります。正規表現で解析されて、それらが何であるかを確認します。

quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/

次に、文字列が ( 以外の) セレクターである場合、jQuery は DOM をトラバースして、その高価な関数idとの一致を見つけます。find

} else if ( !context || context.jquery ) {
    return ( context || rootjQuery ).find( selector );
}

はい、それは高価ですが、それはセレクターにのみ当てはまります!

を渡すとDOMElement、jQuery が行う唯一のアクションは、新しく作成された jQuery オブジェクトのコンテキストとして DOMElement パラメータを保存し、コンテキストの長さを 1 に設定することです。

// Handle $(DOMElement)
if ( selector.nodeType ) {
    this.context = this[0] = selector; // Selector here is a DOMElement
    this.length = 1;
    return this;
}

jsPerf でいくつかのテストを行ったところ、実際に jQuery オブジェクトをキャッシュしてもほとんど効果がないことがわかりました。

以下で説明する棒グラフ

Chrome では 7% しか遅くありません。(IE ではもう少し重要で、12% です。)

于 2012-05-03T14:02:15.877 に答える
14

2 番目の質問に答えるには、ソースを見てください。

// Handle $(DOMElement)
if ( selector.nodeType ) {
    this.context = this[0] = selector;
    this.length = 1;
    return this;
}
于 2012-05-03T14:04:54.127 に答える
10

パフォーマンスの違いに関しては、2 つの直接比較を探している場合は、DOM 選択や直接関係のない他のメソッドなど、結果をゆがめる可能性のある余分なコードを削除すると役立ちます。

http://jsperf.com/this-cost/2

ここに画像の説明を入力

より現実的な設定では、テストが示したように相対的な違いはわずかです

もう 1 つ覚えておくべきことは、jQuery オブジェクトを作成するたびにメモリを割り当てる必要があるということです。これにより、ガベージ コレクターが実行する必要のある作業が増えます。

人々がキャッシングを提案する理由は、ある程度原則的な観点からだと思います。通常は目立った影響はありませんが、最終的には簡単に回避できるオーバーヘッドが必要になる余分な作業が行われています。

于 2012-05-03T15:23:31.277 に答える
8

ここでのすべてのランタイム パフォーマンス テストで見逃していることの 1 つは、もう 1 つの重要な考慮事項です。

ネットワーク帯域幅。

ローカル変数にキャッシュ$(this)すると、一般的にスクリプトのサイズが縮小されます。特に縮小すると ( this4 文字から縮小できないため)。

検討:

function hello(text) {
    $(this).attr();
    $(this).css();
    $(this).data();
    $(this).click();
    $(this).mouseover();
    $(this).mouseleave();
    $(this).html(text);
}
hello('Hello world');

Closure コンパイラの縮小出力は

function hello(a){$(this).attr();$(this).css();$(this).data();$(this).click();$(this).mouseover();$(this).mouseleave();$(this).html(a)}hello("Hello world");

これにより、39 バイト (20%) 節約できます。今考えてみましょう:

function hello(name) {
    var $this = $(this);
    $this.attr();
    $this.css();
    $this.data();
    $this.click();
    $this.mouseover();
    $this.mouseleave();
    $this.html(name);
}
hello('Hello world');

縮小された出力は

function hello(b){var a=$(this);a.attr();a.css();a.data();a.click();a.mouseover();a.mouseleave();a.html(b)}hello("Hello world");

これにより、74 バイト (37%) 節約され、バイトの節約はほぼ 2 倍になります。明らかに、大規模なスクリプトでの実際の節約はこれより少なくなりますが、それでもキャッシュによってスクリプトのサイズを大幅に削減することができます。

本当に、キャッシングには利点しかありません$(this)。ごくわずかですが、測定可能なランタイム パフォーマンスの向上が得られます。さらに重要なことは、ネットワーク上を移動するバイト数を減らすことができ、ページの読み込みが速いほど売り上げが増えるため、直接的により多くのドルに変換できます。

そのように考えると、実際には、繰り返してキャッシュしないことには定量化可能なコストがかかると言えます。$(this)

于 2012-05-04T02:26:36.090 に答える