47

を使用すること$("#vacations").find("li").last()は、よりも優れた方法$("#vacations li:last")ですか?

背景と私の考え:

私は素敵なインタラクティブな試行jQueryチュートリアルで遊んでいましたが、タスクの1つは次のように述べています:

コードを調べていると、他の誰かが $("#vacations li:last") で最後の休暇を選択していることに気付きます。あなたはこれを見て、「トラバーサルならこの道がもっと速くなるだろう!」と思います。これらの考えに基づいて行動し、このコードをリファクタリングして、代わりにトラバーサルを使用して #vacations 内の最後の li を見つける必要があります。

なぜそう思うのでしょうか?私にとって、セレクターの使用は、トラバースよりも少し高いレベルに見えます。私の考えでは、セレクターを指定しているとき、必要な単一の結果をより適切に取得する方法はjQuery次第です(中間結果を返す必要はありません)。

複合セレクターを使用することによる余分なオーバーヘッドは何ですか? セレクターロジックの現在の実装が文字列を解析し、トラバーサル API を使用しているためですか? 文字列の解析が遅いですか?将来の実装で、中間結果を返す必要がなく、トラバーサルよりも高速であるという事実を使用する可能性はありますか?

4

2 に答える 2

21

これに対する明確な答えはありません:lastが、使用しているセレクターに関しては、セレクター API 標準の独自の拡張機能です。.querySelectorAllこのため、ネイティブメソッドでの使用は有効ではありません。

Sizzle が行うことは、基本的にセレクターを で使用しようとすること.querySelectorAllです。無効なセレクターが原因で例外がスローされた場合、純粋な JavaScript ベースの DOM 選択/フィルタリングがデフォルトになります。

これは、次のようなセレクターを含める:lastと、ネイティブ コードで DOM 選択の速度が向上しないことを意味します。

さらに、ID や要素名など、セレクターが非常に単純な場合は、ネイティブのgetElementByIdgetElementsByTagNameが使用されるように最適化が組み込まれています。これは非常に高速です。通常は よりもさらに高速ですquerySelectorAll

また、この.last()メソッドはすべてのアイテムをフィルタリングするのではなく、コレクションの最後のアイテムを取得するだけなので、これは Sizzle フィルターが通常行っていることです(少なくとも以前はそうでした)

IMO、独自のものには近づかないでください。現在、これ.querySelectorAllはかなり普及しており、標準に準拠したセレクターのみを使用することには真の利点があります。DOM 選択後にさらにフィルタリングを行います。


の場合$("#vacations").find("li")、中間結果は気にしないでください。これは をgetElementById続けて使用しgetElementsByTagName、非常に高速になります。

速度が非常に気になる場合は、jQuery の使用を減らし、DOM を直接使用してください。


現在、 のようなセレクターのドキュメントには:last、パフォーマンスの低下について警告するメモがあります。

:last は jQuery 拡張機能であり、CSS 仕様の一部ではないため、ネイティブ DOMメソッド:lastによって提供されるパフォーマンスの向上を利用するクエリを使用することはできません。querySelectorAll()を使用して要素を選択するときに最高のパフォーマンスを実現するには:last、最初に純粋な CSS セレクターを使用して要素を選択し、次に を使用します.filter(":last")

しかし、私はそれ.filter(":last")が良い代用品になることに同意しません. .last()セットをフィルタリングする代わりに、要素を直接ターゲットにするようなメソッドの方がはるかに優れています。標準に準拠していないセレクターを使い続けてほしいという気持ちがあります。IMO、あなたはそれらを忘れたほうがいいです.

于 2013-03-05T06:25:09.740 に答える
14

セットアップのテストは次のとおりです: http://jsperf.com/andrey-s-jquery-traversal

jQuery のセレクター エンジンであるSizzlegetElementByIdは、正規表現を使用して文字列を解析し、 と を使用して非常に基本的なセレクターを高速化しようとしgetElementsByTagNameます。#fooセレクターがandよりも複雑な場合は、有効な CSS セレクターのみを受け入れるimgを使用しようとします( 、、またはその他の jQuery 固有の疑似セレクターはありません)。querySelectorAll:radio:eq:checkbox

セレクター文字列は読みにくく処理速度も遅いため、使用する理由はまったくありません。

#idセレクター文字列を、Sizzle がすばやく解析できる単純なチャンク ( and )に分割することtagnameで、基本的に、 and への呼び出しを連鎖させるだけでgetElementByIdありgetElementsByTagName、これは可能な限り高速です。

于 2013-03-05T06:29:15.423 に答える