14

JSP でこの jQuery セレクターを複数回使用しています。

 $("#customers tbody tr td input[type='checkbox'][name='selectedCustomers']")

いくつかのブログで見つけた解決策は、最初に行うべきことです。

var customer=$('#customers')

そして、上記の顧客オブジェクトを使用して、さらに呼び出しを行います。

 customer.find("tbody tr td input[type='checkbox'][name='selectedCustomers']")

私の質問は、この解決策は何か違いを生むのでしょうか、そしてその理由は何ですか?

私の理解

私がする時

$("#customers tbody tr td input[type='checkbox'][name='selectedCustomers']")

div id="customers" jQuery は内部的に最初に(document.getElementById("customers") によって) 関連付けられたオブジェクトを取得し、次に指定されcheckboxた . そして、提案された解決策に従えば、document.getElementById("customers")一度だけ解雇され、残りは同じになります。だから私は不要な複数から身を守っていますdocument.getElementByIdが、残りは同じです。私の理解は正しいですか?はいの場合、私の知る限りではdocument.getElementById、よりコストのかかる操作ですか?

編集:-

上記のセレクターを複数回使用しているだけでなく、div id="customer" の下にある他の可能なセレクターも使用しています。もう一度質問しますが、顧客オブジェクトを最初にキャッシュする場合とキャッシュしない場合のパフォーマンスの違いは何ですか?

4

4 に答える 4

6

それほど具体的である必要はありません。私は、せいぜいこれを推測しています:

$('#customers td [name="selectedCustomers"]')

...これにより、パフォーマンスが向上するはずです。次に、実際にselectedCustomers毎回クエリを実行している場合は、すべてをキャッシュする必要があります。

var selectedCustomers = $('#customers td [name="selectedCustomers"]');

それ以外の場合、名前が動的で、ページごとに同じ名前のアイテムが 1 つしかない場合...

var item = $(document.getElementsByName(someName)[0]);

一方、単にキャッシュ$('#customers')するのはほとんど無意味です。.findonは、特にサポートcustomersがあれば、そもそもセレクター全体と同じくらい多くの作業を行います。querySelector

于 2012-12-22T15:21:40.100 に答える
3

オブジェクトをキャッシュするという基本的なポイントが欠けているようです。オブジェクトがキャッシュされると、そのセレクター内のそれ以降のトラバーサルまたは操作は格納されたオブジェクトに対して実行され、DOM を検索して最初にセレクターを見つけ、それを使用する必要があるたびにコレクションを作成する必要はありません。

コレクションに変更を加える前に、ドキュメントの検索を呼び出すたび$("#customers tbody tr td input[type='checkbox'][name='selectedCustomers']")に要素のコレクションを作成する必要があります。

コレクションをキャッシュすると、それ以上検索を行う必要がないため、パフォーマンスが向上します

/* locate and store the collection once*/
var $checkboxes=$("#customers tbody input[name='selectedCustomers']");
/* look within previously stored collection*/
$checkboxes.filter(/* expression*/ ).doSomething();

document.getElementByIdjQuery ライブラリによる追加の関数呼び出しを必要としないため、jQuery 検索よりも高速に使用できます。ただし、次のように結果を jQuery オブジェクトとして使用する場合: オブジェクト $( document.getElementById('foo')) をキャッシュするための 1 回の使用について心配する価値はないでしょう。

于 2012-12-22T15:25:56.920 に答える
1

だから私は不要な複数から身を守っていますdocument.getElementByIdが、残りは同じです。

はい。ただし、セレクターは右から左に評価されるため、そうでない場合もあります (この記事またはこの SO の質問を参照してください)。#customersまた、エンジンが効率的であると仮定すると、最初にドキュメント ツリーを選択し、次にそのドキュメント ツリーの一部でのみその評価を行う場合は、作業が少なくてすみます.find()。しかし、私はそれについて100%確信が持てません。

document.getElementByIdよりコストのかかる操作ですか?

いいえ、とても安いです。Id は、単一の要素を識別するための標準的な属性であり、ブラウザーは非常にパフォーマンスの高いルックアップ テーブルを作成しますO(1)

customer.find("tbody tr td input[type='checkbox'][name='selectedCustomers']")

一方、DOM ツリーを評価する必要がある DOM セレクター クエリは非常にコストがかかります。特に、ネイティブではなく JS コード (jQuery sizzle) で手動で行う場合は、非常にコストがかかりますが、このかなり単純なクエリネイティブに委譲されますquerySelectorAll

それ#customersがあなたのテーブル要素だと思います。したがって、パフォーマンスのために、tbody tr tdタグを省略してください。タグは必須です ( <thead>/<tfoot>または<th>要素からチェックボックスを明示的に除外するためにタグを使用していないと仮定します)。いずれにせよ、 をテーブル要素の直接の子として見つけることはできません<input>。また、セレクター エンジンが行うことははるかに少なくなります。

さらに、マークアップをよく知っていて、チェックボックスだけがそのname属性を持っていると仮定できる場合は、tagname および type 属性セレクターも省略できます。これは、ネイティブにデリゲートできることを意味しますgetElementsByName。これにより、パフォーマンスが少し向上するはずです。

$(document.getElementById("customers").getElementsByName("selectedCustomers"))

要素がチェックボックスであることを確認する必要がある場合でも、それらをフィルタリングできます。それで、あなたはで終わるかもしれません

$(customer.get(0).getElementsByName("selectedCustomers")).filter(":checkbox")

ただし、パフォーマンスの向上を証明するには、テスト、テスト、テストしかできません。実際のフルページでそれを行う必要があります。

于 2012-12-22T20:09:11.213 に答える