自分のためのメモ代わりとして、気になった部分をピックアップ。
まずポイント列挙
JavaScriptコード上でよく見られる性能劣化ポイント(抜粋)。以下、まず列挙します。リンクはページ内アンカです。
意図しない変数のグローバル化
JavaScriptでは、関数内で変数を参照する際にまず自身のスコープ内を探します。見つからない場合、入れ子になっている関数であれば外側の関数のスコープをたどっていき、グローバルスコープは必ず最後に探索されます(スコープチェイン)。そのため、グローバル変数を発見するのは時間がかかることになります。
また、「var」をつけずに宣言された変数はグローバル変数となります。
なので、グローバルにする必要のない変数は必ず「var」を付けて宣言しましょう。
関連:JavaScriptのクロージャ、スコープチェインについての記事(World Wide Windblue)
コストの高い配列アクセス方法を利用
配列にアクセスするには、以下の2通りの方法がある。- メソッド呼び出し
後発で使用追加されたメソッドを呼び出すこと。(Array.pushなど) - プリミティブ操作
原始的なアクセス方法
プリミティブ操作を使用するほうがパフォーマンスが高くなる。
try/catchの間違った使用
catch節が実行されるたびに新しいスコープが生成・破棄されるため、頻繁に実行されるとパフォーマンスが低下する可能性があります。入力チェック時などエラー判定をするときなどでも、別の方法があるならtry/catch節を排除することが望ましいケースが多いでしょう。
2010 11/1 追記ここから
実際に試してみる。
エラー判定にtry/catchを使わない場合と使った場合で比較。
比較したブラウザはIE7、Firefox3.6.8、Google Chrome7、Opera10.63。
各検証を10回して平均を取った。
エラー判定にtry/catchを使わない場合。
window.onload = function(){ var start = new Date(); for(var i = 0;i < 10000; i++){ var a = 100; if(typeof a === 'string'){ return a.substring(0, 2); }else{ } } var end = new Date(); alert((end - start)); }
1回の実行にかかった平均の時間。
IE…11(ms)
Firefox…0.6
Google Chrome…0
Opera…1.9
エラー判定にtry/catchを使わない場合。
window.onload = function(){ var start = new Date(); var a = 100; for(var i = 0;i < 10000; i++){ try{ a.substring(0, 2); }catch(e){ } } var end = new Date(); alert((end - start)); }
1回の実行にかかった平均の時間。
IE…540.7(ms)
Firefox…760.7
Google Chrome…1395
Opera…28.9
(Operaが早すぎて不安です。PCのスペックが低いのも関係あるかもしれません)
2010 11/1 追記ここまで
また、catch節の実行時に生成されるスコープは、ローカルスコープよりも上位に位置します。
そのため、catch節の中で変数を定義することは、それだけで処理のオーバーヘッドになります。
ダメな例。
try{ ... }catch(error){ if(error.code === '500'){ var c = error.code; ... } }
この倍、errorオブジェクトに対する処理は別の関数に委譲するコトでパフォーマンスへの影響を最小限に抑えられる。
関数かされた処理はcatchスコープから呼び出されても、ローカル変数は通常のローカル変数スコープ内に定義されます。
よい例。
try{ ... }catch(error){ handleError(error); }
ブラウザの再描画について
JavaScriptによりDOM要素の位置やサイズ変更、新たなDOM要素の追加などを行うと、ブラウザはその変更を表示されているWebページに反映しなくてはなりません。このような場合にブラウザの再描画が発生しますが、再描画に要するコストは高く、頻繁に発生すると深刻なパフォーマンス低下を招きます。
再描画の回数を減らすポイントは次の2点。
- DOMに対する「スタイルの取得」と「スタイルの変更」を混ぜない
- DOMに対する「スタイルの変更」は短時間ですばやく行う
0 件のコメント:
コメントを投稿