[PhpStorm/WebStorm]jQueryの非効率な使い方をすると警告してくれるようになった
iOS6 のマップって不便って騒がれたけど、それほどでもないよね?…って思ってましたが、最近お店探しで使って全然見つからなかったので、さすがにこれは…と思いMapion インストールしました。使いやすいですね…
今日は、だらしない明らかに非効率なjQueryなコードを書くとやんわりと指摘してくれるPhpStorm/WebStormの機能「Inspection: jQuery usage efficiency 」を紹介します。(バージョン5.0以降)
非効率なjQueryのコード
っていったいどんなコードなのか。具体的には以下のようなコードです。
$("p").addClass('hover');
$("p").toggle();
実際にはこんなコードを書いているわけではありませんが。このコードの何が非効率かというと、$("p")
が2回実行されている、ということですね。内部的にはdocument.getElementsByTagName("p")
を呼び出していると思いますが、DOM全体からp要素を検索するのを2度行っています。
こんなコードを書くと次のような警告を発します。
気をつけていれば上記のようなコードを書くことはまずありませんが、それでも処理が10行超えてくるとやっちゃうこと、あります。
改善例
上記の例は明らかに非効率ですが、改善するには以下の2パターンがあるかと思います。メソッドチェインさせるように書き換えるのが楽ですが、コードがわかりにくくなる、と感じたら変数に代入してから処理するのも手です。
// 改善例1: メソッドチェインをつかう
$("p").addClass('hover').toggle();
// 改善例2: 変数に入れる
var $target = $("p");
$target.addClass('hover');
$target.toggle();
idセレクタが先頭にある複合セレクタ
次のコードでも警告してきます。
$("#id p").click(function() {
// なにかする
});
こちらについては警告部分にカーソルを合わせて行先頭にマウスカーソルを合わせると表示される豆電球アイコンをクリックして、「Preface with ID Selector」を選ぶと自動修正されます。(↓変換後)
$("#id").find("p").click(function() {
// なにかする
});
idは単体で取得した方がいいらしいです。特定の#idを持つ要素の子孫のpが必要な場合はまずidを取得してからフィルタさせるといいらしいです。ホントか!?と思ったのでベンチマークとってみました。ベンチマーク関数は関数の実行時間を得る - nazonoDiaryを参考に。(最近のブラウザはステータスバーがないのが多いのでコンソールに出力しています)
Function.prototype.bench = function(st){
var self = this; // 実行時間を計りたい関数
return function(){
var start = new Date().getTime();
var res = self.apply(this,arguments);
var end = new Date().getTime();
console.log(st+":"+(end-start)); // 結果をコンソールに表示
return res;
}
}
var test = function(){
for(var i=0;i<10000;i++){
$('#container div');
}
};
var test2 = function(){
for(var i=0;i<10000;i++){
$('#container').find('div');
}
};
var t = test.bench("実行時間");
var t2 = test2.bench("実行時間2");
t(); // => Safari on Mac で 270 〜 280ms
t2(); // => Safari on Mac で 210 〜 220ms
上記のコードをシーブレインのサイトで実行します。結果は
- Safari で 280ms → 220ms
- Chrome on Macで 214ms → 187ms
- Firefox(Firebug有効) on Macで 482ms → 344ms
- IE9 on Windows7(VMWare Fusion)で 498ms → 211ms
でした。2〜3割減ってました!
まとめ
非効率なコードを指摘してくれるといっても何もかも教えてくれるわけではなく、紹介したもの以外には見つけることはできませんでした。( $("div p") と$("div p span") だと警告されませんでした。)それでも初歩的なミスはなくなりますし、jQueryなコードを書くときの習慣を変えられそうなので、私はとてもお世話になってます。