作ったWebサービスの表示速度を20倍以上早くした方法について(jQuery編)
ども、Ruby on RailsでanIRankingっていうWebサービスを作ったのですが、使い勝手がイマイチでjQueryっていうJavaScriptのライブラリを勉強してUIを改善中な昨今です。
というわけで、手始めに実際に使ってくださったユーザの方何名かから要望いただいた「検索」機能について実装を考えてみました。
◆遅いコード
最初に書いたのが以下のコードです。後述しますが、アニメタイトルが増えれば増えるほどめっちゃ遅くなります。
$('form').submit(function(){ var SearchWord = $('#inputsearch').val(); //テキストボックスの値取得 var WordCount = $('span').length; //spanタグの数を取得(約9,000件) //spanの数だけ繰り返し実行 for (var i = 1; i < WordCount; i ++) { var ContentWord = $('span').eq(i).text(); //spanタグ内のテキスト取得 //spanタグ内のテキストがテキストボックスの値に一致するか(部分一致) if ( SearchWord.indexOf(ContentWord) != -1 ){ //一致した場合は表示 $('span').eq(i).addClass('showlist'); }else{ //一致しなかった場合非表示 $('span').eq(i).removeClass('showlist'); } } return false; });
アニメのタイトルはhtmlで「タイトル」で指定していて、for文で全てのspanタグをチェックして、検索テキストボックスに一致する場合は、表示させるための「showlist」クラスを追加します。
spanの数が100件程度なら上記コードで問題なく検索結果が帰ってくるのですが、9,000件のアニメタイトル相手に実行すると処理が遅い…というか、もはやハングアップしていると見なされてChromeが警告を出してくるレベルです。
◆早いコード
それで、どうしたものかと途方にくれていたのですが、色々試した結果以下の方法で爆速になりました。
jQueryのcontainsというのを使うと、指定した文字列に部分一致する要素に対して一括でcssを追加することができます。使い方は「<要素>:contains("<文字列>")」な感じ。詳しくは以下サイトなど見ていただければと思います。
http://semooh.jp/jquery/api/selectors/%3Acontains/text/
$('form').submit(function(){ var SearchWord = $('#inputsearch').val(); //テキストボックスの値取得 //spanタグを一旦非表示に設定 $('span').removeClass("showlist"); //spanタグの内、テキストボックスの値に一致(部分一致)するタグを表示 $("span:contains(" + SearchWord + ")").addClass("showlist"); return false; });
最初に書いたコードに比べて非常に短くすむ上に速度はめっちゃ早いので良い事だらけですね。
◆最後に
こう書くと簡単に思えるかもですが、このコードに行き着くまでかなり時間がかかりました・・・。
ProgateっていうサイトでjQueryについて学んだのですが、どうしても学んだ範囲内でなんとかしようとしちゃって、なかなか他にもっと良いやり方があるんじゃないかっていう思考に行き着かなかったんですよねぇ。(そのおかげで、jQueryはclass指定よりid指定の方が読み込みが早いとか高速化の知識が少し増えましたが)
行き詰まってようやく、一旦ゼロから考えて何かいい方法がないか探し始めたところ、あっさり良い方法が見つかるという体験を得ました。既存の(今のところ)問題なく動いている機能とかも「もっと他に良いやり方がないかな」とか考えてみるのも視野が広がって良さそうですね。