問題提起
受託案件でフロントエンドの処理が遅いことでリファクタリングが必要になりました。
解決方針
まずチームで考えた結果、フロント側に描画する前に
ajax通信を使ってDBから取得したデータを処理するロジックに問題があるのではないか、というものでした。
が、自分的に描画部分に問題があるんじゃないかと思い、
ロジックを修正する前に描画部分の処理に着目しました。
js、jQuery構文で処理を高速化する書き方があるんじゃないかと考えたからです。
解決
結論、js、jQueryのちょっとした書き方の違いで早くなりました!
処理速度が1/3に!
改善前ソースコード(一部抜粋)
for (var i = 0; i < hoge.length; i++) {
var selector = '[data-name=hogehoge]';
$(selector).find('.values li input').each(function(){
...
}
...
}
(※上記のような処理が何個もある...)
改善後ソースコード(一部抜粋)
for (var i = 0, len = hoge.length; i < len; i++) {
var selector = '[data-name=hogehoge]';
$(selector + ' ' + '.values li input').each(function(){
...
}
...
}
修正内容は、2点。
1点目、
for内にlengthを使わないように修正。
これについて、forが回るたびにlengthの処理が行われるので、
そりゃ遅くなりますよね。
実は、phpでも同じ事が言えて、
forの中でcount()を使うと処理が遅くなるんですよね。
forの前にcount()で取得した数を変数に入れて、forを回して上げるのが早い!
2点目、
セレクタ指定は、findで処理するより、セレクタをシンプルに書いた方が処理が早いとのことだったので、
「セレクタをシンプルに!極力、findは使わない!」てな感じで修正。
ここでもう一度コードを見直してください。
改善前ソースコード(一部抜粋)
for (var i = 0; i < hoge.length; i++) {
var selector = '[data-name=hogehoge]';
$(selector).find('.values li input').each(function(){
...
}
...
}
改善後ソースコード(一部抜粋)
for (var i = 0, len = hoge.length; i < len; i++) {
var selector = '[data-name=hogehoge]';
$(selector + ' ' + '.values li input').each(function(){
...
}
...
}
上記を見ていただける通り、
少しの修正で高速化するので、
一度ソースコードを見直してみると高速化できる箇所があるかもしれません。
この考え方に至った背景
自分は前職ゲーム会社で働いていました。
web業界、共通で言われることだと思いますが、
「ユーザーが待てるのは2秒、3秒以上待たせたらユーザーは離れていく」と教えられてました。
そのため、前職では「phpの構文から処理速度を高速にすること」というルールが決まっていたので、
「jQueryも構文によって、処理高速化できるっしょ!」的な感覚で調べてみました。
さいごに
この修正でロジック的に速度を速くすることを考える前に
コーディングルールで処理速度を考えておくことも
大事ってことを再認識しました。