jQueryのセクレタ指定は便利ですが、その裏側ではJavaScriptの処理が走っています。
その為に指定の仕方によってJavaScriptの処理内容が異なる為、処理が無駄に動いて負荷が高くなっている場合もあります。
代表的な指定方法を例に、どういった指定が高負荷になるかを整理したいと思います。
セレクタ指定の重い/軽いのポイントは、JavaScriptにメソッドが用意されているか、検索対象の数の多さ、この2点が重要なポイントとなります。
基本的な指定方法による速度の違い
一番早いID指定
ID指定が一番高速です。これはJavaScriptのメソッドに getElementById() が用意されている事と、検索対象が一意の存在である事に起因しています。
- $('#id');
次に早い要素・クラス指定
要素指定は getElementTagName() が、クラス指定は getElementsByClassName() がJavaScriptで用意されているので、ID指定の次に高速な指定方法となります。どちらも対象要素は複数存在するので、id指定より少し低速となります。
- $('div');
- $('.class');
少し遅い属性指定
属性指定は querySelectionAll() が用意されていますが、要素・クラス指定に比べ処理が遅くなります。
その理由として getElementsByTagName() は動的なNodeListを扱うのに対して、querySelctorAll()は静的なNodeListで扱うことの違いが大きく作用しています。この事に関しては詳細な情報がマイナビニュースに記事があったので、興味のある方はご覧下さい。
- $('[name="radio"]');
[外部] getElementsByTagName()がquerySelectorAll()より高速な理由(マイナビニュース)
遅い指定方法
上記以外はJavaScriptのメソッドが無いので、jQueryで用意されたオリジナルの処理が動きます。その為大きくパフォーマンスを落とします。例えば「:checked」といった指定です。
- $('[name="radio"]:checked');
パフォーマンス改善のポイント
改善1:不要な指定を省く
jQueryではセレクタの指定は左から右に紐解かれて行きます。不要な指定が増えると処理負荷が増してしまいます。
例えば、ID名の前にdivといった要素指定を入れてしまうと、全てのdiv要素から検索してしまう為、div要素が増えるほど無駄な検索が増えてしまいます。id名のみで指定するようにするのがポイントです。
- $('div#id'); ID名の前に要素は入れない
- $('#id'); 同じ意味だがこちらの方が早い
改善2:処理が早い指定で絞り込んでおく
クラス名や要素名で指定する場合は、ID名で絞っておくと、検索対象が少なくなるので、検索の軽減に繋がります。
- $('.class'); #body要素配下の.classが対象
- $('#id .class'); #ID要素配下の.classが対象で、上記より対象が少ない
改善3:要素の何番目かを指定する
要素指定であっても、一つ目など検索対象先を絞ることで、処理の改善が期待できます。
- $('.list li'); クラス=list配下の li要素全てが対象
- $('.list li').eq(0); クラス=list配下の li要素の1番目のみが対象
最後に
冒頭でも書きましたが、裏側ではJavaScriptが動いているので、$('#id')は、 getElementById('id') とJavaScriptの記述で書いた方が早いです。
ただ、よほど複雑なコードの書き方をしていなければ、jQueryの高速化よりも外部ファイルの読込みを数を減らしたり、画像の容量を軽量化するほうがサイトパフォーマンスの改善が期待できるのが正直なところです。
少しでもサイトパフォーマンスを上げたい方は、上記のような事を頭の片隅に置きながらjQueryの記述に気にかければ、より読込みに負荷が掛からないサイトになると思います。