jQuery のセレクタをキャッシュしてみたら180倍くらい早くなった。 キャッシュすべし!


初心者だった頃、誰しも一度くらいはこんな感じのコードを書いたことがあるのではないでしょうか?

$('#js-button').on('click', function () {
    $(this).text('click');
});

$('#js-button').on('mouseenter', function () {
    $(this).text('mouseenter');
});

このコードのどこが問題かというと、$('#js-button')を2回、$(this)を2回書いてしまったところです。

全く同じ処理を4回も行うのは明らかに非効率ですよね。

だから、以下のように、一旦戻り値のjQueryインスタンスオブジェクトを変数にキャッシュしておいて、あとからその変数を参照するようにしたほうが処理が1回で済むので、パフォーマンスが良いです。

var $button = $('#js-button');

$button.on('click', function () {
    $button.text('click');
});

$button.on('mouseenter', function () {
    $button.text('mouseenter');
});

「でも… いちいち面倒だよなー」

いいのですが、このような再利用のためだけにとっておいた変数が増えてくると、管理が面倒になることもあるでしょう。

特にモジュールなんかを使ってると、他のモジュールでも再利用したい場合、再利用したい変数をグローバルからでもアクセスできるようにしないといけなくなるので、何かと面倒なんです。

それに、下記コードの場合だと、$(this)の戻り値が必ずしも常に同じとは限らないので、再利用しづらいです。

$('.button').on('click', function () {
    $(this).text(this.value);
});

解決策、「勝手にキャッシュしてくれる」ラッパー関数を作る

いちいち「戻り値を変数に入れて再利用しなきゃ」という強迫観念から解放すべく、$$という便利なラッパー関数を作りました。

キャッシュしたいところで$に置き換える感じで使います。

$$('.button').on('click', function () {
    $$(this).text(this.value);
});

$$('.button-2').on('click', function () {
    $$(this).text(this.value);
});

キャッシュを更新したい場合は第2引数をtrueにすればいいのです。

$$('.button-2',true)

結論

テストしてみたところ、Chrome 43 の環境で、平均で大体180倍くらい早くなりました。

もちろん、キャッシュしたからと言って体感速度が変わるわけではないと思いますが、私みたいなパフォーマンスが気になる人は気になっちゃうものですw 素早く動きまわる我が家のプーティをアイキャッチに使ってますが、実際は速くなっても気づかないのです…

気休めにしかならないと思いますがw、良かったら試してみて下さい!

jquery-selector-cache(GitHub)

npm install jquery-selector-cache -Dでもインストールできます(AMDとCommonJS対応)。


ABOUTこの記事をかいた人

Hi, 中国四川出身の王です。2008年に日本に渡り、大学卒業後Web制作会社勤務を経て、現在はフリーランスとしてゆるりと働いています。サイト制作の全般を担当しています。好きな生き物はプーティ(マイCat)です。趣味はアニメ鑑賞です。画家になるのが夢だったりします!