「IEにおけるJavascriptパフォーマンスについてのススメ」を読んだメモ
IEBlog:IEBlog : IE + JavaScript Performance Recommendations - Part 1
IEBlogをがんばって読んだのでメモ。内容的には既出のものが多いのであまり参考にならないかも。
この記事は以下3つパートで構成される
- シンボルの検索のパフォーマンスについて
- 効果的じゃないJavaScriptコード
- IEにおいて考慮すべきスクリプトのパフォーマンスについて
以下は1番の「シンボル検索のパフォーマンスについて」の要点
ローカル変数を使用する
ローカル変数の参照はスコープチェーンをたどらなくて済む(検索の範囲が狭い)のでパフォーマンスが向上する。
また、意図しないグローバルスコープの変数を定義したり参照したりすることを防ぐ。
オブジェクトの参照をキャッシュする
ドットでオブジェクトのプロパティを参照するのはパフォーマンス低下させる。
ので、オブジェクトのプロパティの参照はできるだけ減らす
以下、コードの例を抜粋
function BuildUI() { var baseElement = document.getElementById(‘target); baseElement.innerHTML = ''; // (1) baseElement.innerHTML += BuildTitle(); // (2) baseElement.innerHTML += BuildBody(); // (3) baseElement.innerHTML += BuildFooter(); // (4) }
上記コードでは、innerHTML
プロパティへの参照が4回発生している。これは以下のように変更できる。
function BuildUI() { var elementText = BuildTitle() + BuildBody() + BuildFooter(); document.getElementById('target').innerHTML = elementText; // (1) }
これだと1回の参照で済む。上記はDOMノードの参照において効果が大きく現れる。
関数ポインタをキャッシュする
関数への参照をローカル変数にキャッシュした場合に早くなるらしい。
function IterateWorkOverCollection() { var length = myCollection.getItemCount(); for(var index = 0; index<length; index++) { Work(myCollection[index]); } }
上記コードでのWork
関数はグローバルスコーブで定義されている関数で、この関数呼び出しのたびにスコープチェーンをたどって関数を探しにいくことになる。
上記コードは以下のように変更できる。
{ var funcWork = Work; var length = myCollection.getItemCount(); for(var index = 0; index<length; index++) { funcWork(myCollection[index]); } }
上記のようにグローバルスコープのWork
関すへの参照(ポインタ)ををローカル変数のfuncWork
に格納し、ループ内でそのローカル変数を使って関数を呼び出すことでパフォーマンスが向上する。
withの使用を避ける
withを使うと新しいスコーブがスコープチェーンに追加される。スコープチェーンを作成するのにコストがかかるのと、withの内側からwithの外側のスコープのプロパティを参照するためにはスコープチェーンをたどる必要があることからパフォーマンスが落ちる場合がある。
以上でパート1は終了。
パート2につづく...かも。
追記:2009.1.28
一応、part2とpart3に目は通したけど、正直あまり理解はできていない。「アクセサメソッドを使うのをやめてプロパティに直接アクセスするようにせよ」というのもあって、「そりゃそうだ」とは思うが、そのようなコーディングには全面的には賛成できない。
パフォーマンスの向上のかわりに可読性やメンテ性を犠牲にしているから。(原文に対するコメントにもそんな意見が多く見られる)
この記事で書いている方法でコーディングすると、マシンにとってはやさしい(効率のいい)コードにはなるが、人間にとっては読みにくくメンテしづらいコードになってしまうと思う。
ので、IEBlogのこの記事についてはここまでにしとく。