jQueryのパフォーマンスを落とさないための注意点

タイトルの通りです。セレクタを使う際の注意点やDOM操作をする場合に気をつけることを書いています。

idセレクタを使いましょう

jQueryでのセレクタは次の順番で速いようです:

  1. idで指定する
  2. タグ名で指定する
  3. classで指定する
  4. 属性で指定する
  5. jQuery独自拡張セレクタで指定する

ってことで特別な理由がなければ#idをセレクタに使ってください。

idで取得するときにタグ名を指定しないように

var $hoge = $('div#hoge');

のような指定の仕方はアウトです。なぜならhogeというidを見つけるためにdiv要素をすべて探す必要があるからです。単に

var $hoge = $('#hoge');

のようにしてください。これでjQueryはJavaScriptのネイティブ関数であるgetElementByIdを使ってオブジェクトを取得します。

クラスセレクタよりも要素セレクタを使いましょう

クラスセレクタよりも要素セレクタの方が速いようです。これは要素セレクタを使うとJavaScriptのネイティブ関数であるgetElementsByTagNameを使えるからです。セレクタを使用する際の優先度としてはid > 要素 > classの順番です。

クラスセレクタでは要素名を指定しましょう

クラスでオブジェクトを取得するときは

var $hoge = $('.hoge');

ではなくて

var $hoge = $('div.hoge');

のように要素名を”.”の前に書く、ということです。

複数の要素を並べるときはidを先頭にしましょう

var $hoge = $('div #hoge')

はアウトです。正解は

var $hoge = $('#hoge div')

です。

複数のidを並べてオブジェクトを取得しないように

var $hoges = $('#hoge #hogehoge')

すごく遅くなるそうです。idセレクタを使うときは一つのidを使うようにしましょう。

コンテクストを直接指定するよりもfind()を使いましょう

var $hoge = $('#hogeid').find('.hogeclass');
var $hoge = $('.hogeclass', '#hogeid');
var $hoge = $('#hogeid', '.hogeclass');

は上から順番に実行速度が速いようです。なのでidでオブジェクトを取得した後にfindメソッドを使う、というのが最も効率的になります。

jQueryオブジェクトのキャッシュを使いましょう

ダメな例が

$('#hoge').css('border','1px solid #000');
$('#hoge').css('background-color','#333');
$('#hoge').fadeIn('slow);

です。正解例は

var $hoge = $('#hoge');
$hoge.css('border','1px solid #000');
$hoge.css('background-color','#333');
$hoge.fadeIn('slow);

になります。わかりますね。$(‘#hoge’)が出てくるたびにgetElementByIdでオブジェクトを取得しようとするから、ダメな例はそれだけ遅くなります。何度も使うオブジェクトはキャッシュしてください。

サブクエリを使いましょう

ある要素の子要素を取得するときは、まず親要素をキャッシュした上で子要素を取得しましょう。つまり

var $parent = $('#parent');
var $child = $parent.find('.child');

var $parent = $('#parent');
var $child = $('child', $parent);

が正解です。

メソッドチェインを使いましょう

先ほどの正解例、

var $hoge = $('#hoge');
$hoge.css('border','1px solid #000');
$hoge.css('background-color','#333');
$hoge.fadeIn('slow);

はメソッドチェインを使ってないという意味でアウトです。正解は

var $hoge = $('#hoge');
$hoge.css('border','1px solid #000')
     .css('background-color','#333')
     .fadeIn('slow);

です。メソッドチェインで一気に処理させましょう。

DOM操作は最小限に抑えましょう

例えば100個のli要素をjQueryで追加する場合を考えましょう。このときのダメな例は

$('#hoge').prepend('<ul id="new-list"></ul>');
for (var i = 1; i < 100; i++) {
    $('#hoge').append('<li>' + i + '</li>');
}

です。このようにするとappendメソッドでDOM操作を100回行うことになります。prependを含めると合計101回です。このような場合は

var newList = '<ul id="new-list">';
for (var i = 1; i < 100; i++) {
    newList += '<li>' + i + '</li>';
}
newList += '</ul>';
$('#hoge').prepend(newList);

のように一旦newListのような変数にすべての要素を詰め込んだ上でprependでDOM操作を行いましょう。これだとDOM操作はたった一回だけということになります。

15個以上の要素にスタイルを適用する場合はcssメソッドではなくてstyleタグを追加しましょう

例えばhogeクラスをもったdiv要素に”color: red”を追加するとしましょう。そのとき、hogeクラスをもったdiv要素が15個以上ある場合は

$('div.hoge').css('color','red');

ではなくて

$('<style> div.class { color: red; } </style>').appendTo('head');

のようにhead要素内にstyleタグを追加しましょう。

\$(document).ready(function)の代わりに\$(function)を使いましょう

$(document).ready(function() {
    // 関数内部
});

$(function() {
    // 関数内部
});

で同じことができます。これでほんのごくわずかですがjsファイルの容量を減らすことができます。

\$(window).loadと\$(document).readyを使い分けましょう

この二つは実行されるタイミングが異なります。\$(document).readyはDOMが構築された時点で実行されますが、\$(window).loadは画像を含めてページの読み込みがすべて完了した後で実行されます。実行されるタイミングが違うわけですから、\$(window).loadでできることはそちらに任せましょう。

Google CDNからjQueryを読み込みましょう

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>

これが一番速くjQueryを読み込めます。

参考サイト

jQuery Performance Tips Cheat Sheet | Dumitru Glavan