2009-09-11 32 views
5

セレクタをどのように表現するかによってパフォーマンスが大きく変化します。たとえば、まったく同じ要素を選択し、これらの2つのセレクタ、見て:そこに1つのコールだけですが、実際には、私はAを見つけることだと速くなるように)私はBに期待jQueryセレクタのパフォーマンス

A) someTableRow.find("td.someColumnClass").find("span.editMode").find("input") 
B) someTableRow.find("td.someColumnClass span.editMode input") 

)の周りを実行8倍速くなります。なぜ誰も洞察力を持っていないのですが?ありがとう

答えて

14

、あなたが見ているパフォーマンスはDOMがあるの変化によるものです横断したhereから:

最大とjQueryを含む セレクタエンジンは、「トップダウン」 (又は「左から右」)様式で働い1.2.6。 jQuery 1.3.x(つまり、Sizzle、jQueryが組み込む)は、DOMの を照会するための「ボトムアップ」(または 「右から左へ」)アプローチを導入しました。あなたの第二の例("td.someColumnClass span.editMode input")で

は、シズルはこれを効果的に行います。

  1. class="editMode"span要素のための祖先ツリーをトラバース、見つかった各input要素についてsomeTableRow
  2. 内のすべてのinputの要素を取得します。 span.editMode要素ごとに
  3. の要素を削除し、class="someColumnClass"の要素を持つtd要素の祖先ツリーをトラバースします。これらの祖先を持たないinput要素を削除します。しかし、あなたは、find()に各呼び出しで明示的に各ステップを修飾するコンテキストを定義し、ダウンそこからを横断しているあなたの最初の例では、これらの祖先

を持っていないinputの要素を削除します。あなたは「トップダウン」アプローチを実施しています。それはgenerally considered a performance booster各ステップ、でコンテキストを渡すと同等です:

$('input', $('span.editMode', $('td.someColumnClass', someTableRow))) 
+0

ありがとうcrescentfresh、意味があります。私たちは実際に1.2.6から1.3.2に移動しました。なぜなら、これまでにまともに速いセレクタが遅くなった(ほとんどが速い)理由が混乱していました。質問 - すばやく、各ポイントのコンテキストを渡すか、連鎖したfind()呼び出しを使用していますか? – JonoW

+0

これらは事実上同等です。 $( 'foo'、 'bar')は実際にjQueryの腹の中で$( 'bar')find( 'foo')にリルートされます。 find()を呼び出すと明示的に2つのCPUサイクルが節約されますが、何も点滅しないと思います。あなたのチームにとって最も読みやすいものを実行してください。私は非常に読みやすいと思う) –

+0

クール、私はfind()が私にとってより直感的だと感じています。 – JonoW

1

より多くのコールが、よりシンプルです。 Bは1つのコールですが、より複雑です。この場合、コールの複雑さはコールの量を大幅に上回ります。

2

検索のコンテキストが縮小されているためです。

ケースBの場合、すべてのDOM要素を検索して条件を満たすかどうかを確認する必要があります。

"td.someColumnClass"以外のものを無視することができる場合は、DOMのサブセットを使用し、 "span.editMode"にないものは無視できます。だから、今すぐ "入力"を見つけるために検索する要素の数がはるかに少なくなっています。ここでは、セレクタのパフォーマンスに非常に興味深い記事があります

+1

someTableRowのDOM全体の子供を通過することなく、どのように「すばやく無視する...」と判断できますか?両方ともchildren要素の完全なセットをチェックし、someColumnClassでtdを探し、そのリストをeditModeで解析し、そのリストを解析して入力します。もう一方は、最初のリストの同じ検索で3つの基準すべてを探します。 – billjamesdev

+0

これらの2つのセレクタは意味が同じなので、jQueryがどちらの場合でも同じ戦略を使用できない理由はわかりません。 –

1

JQueryがselctorsを処理する方法は、私の経験ではCSSと少し異なります。

Joshが指摘したように、検索のコンテキストを縮小することが重要です。

Iこれは賢明なスピードを比較しない方法

本当に速い2つのパラメータのセレクタを使用して見つけますか?

ここにすべてのヴァーサーが必要なわけではありません。私が行っていることを明確にするだけです。

var columnClasses = $('.someColumnClass'); 
var tableCell = $('td', columnclasses); 
var editMode = $('.editmode', tableCell); 
var spanInside = $('span', editMode); 
var inputFinally = $('input', spanInside); 

優しさ、あなたは(シズルを追加してIE)少なくともjQueryの1.3を使用していると仮定

ダン

1

私はjQueryのセレクタのパフォーマンス自分自身にいくつかの研究をしました。大きな問題は、Internet Explorerのclassnameによる検索です。 IEはgetElementsByClassNameをサポートしません。したがって、jQueryやその他のフレームワークは、すべてのDOM要素を反復処理することでJavaScriptで「再実装」します。 jQuery Selector Performanceについて