高性能javascript学習まとめ(2)--DOMプログラミング
4989 ワード
私達はDOMの操作に対してすべて非常の消耗性能であることを知っています.どうして性能を消耗しますか?
ドキュメントオブジェクトモデル(DOM)は、言語とは独立して、XMLとHTMLドキュメントを使って動作するアプリケーションインターフェース(API)です.ブラウザでは、主にHTMLドキュメントと接触し、WebアプリケーションでXMLドキュメントを検索することもよくあります.DOM APIは主にこれらの文書のデータにアクセスするために用いられる.DOMは言語とは無関係なAPIであるが、ブラウザ内のインターフェースはJavaScriptで実現される.クライアントのほとんどのスクリプトプログラムは、ドキュメントとのつきあいで、DOMはJavaScriptコードの日常的な行動の中で重要な構成部分となります.
一、再絵と再組み版
ブラウザがすべてのページHTMLタグをロードし終わったら、JavaScript、CSSの後、ファイルを解析して二つの内部データ構造を作成します. 一本のDOMツリーはページ構造を表します.レンダリングツリーはDOMノードがどのように表示するかを示しています.レンダリングエンジンはまずHTMLドキュメントを解析して、DOMツリーに変換します.これは第一歩です.次にインライン式であれ、インライン式であれ、インライン式であれ、導入されたCSSスタイルであれば、他のDOMツリーをレンダリングするためのツリー・レンダリングツリーをレンダリングし、レンダリングツリーは、色、サイズなどの表示属性を持つ矩形を含み、これらの矩形の順序は表示順と一致する.レンダリングツリーには、各表示が必要なDOMツリーノードのために、少なくとも1つのノードが格納される(レンダリングツリーにはDOM要素が隠れている).ツリー上のノードを「枠」または「箱」と呼び、CSSモデルの定義に符合し、ページ要素を充填、エッジ、枠と位置を有するボックスと見なす.DOMツリーとレンダリングツリーの構造が完了すると、ブラウザはページ上の要素を表示(描画)することができます.
DOMが要素の幾何学的属性(幅と高さ)に影響を与えるように変化すると、外枠幅や段落にテキストを追加するなど、一連の後続動作が起こる.ブラウザは要素の幾何学的属性を再計算する必要があり、他の要素の幾何学的属性や位置もそのために変更される.ブラウザは、レンダリングツリーに影響を与えた部分を無効にし、レンダリングツリーを再構築する.このプロセスはリメイクと呼ばれています.再レイアウトが完了すると、ブラウザは再描画中に画面に影響を受けた部分を再描画します.
すべてのDOM変化が幾何学的性質に影響するというわけではない.例えば、要素の背景色を変えることは、幅や高さに影響を与えません.この場合、リメイクだけが必要です.要素のレイアウトは変わりません. リメイクとリメイクは重い操作を負担しており、Webアプリケーションのユーザーインターフェースが応答を失う可能性があります.では、リメイクはいつ発生しますか?
1、可視DOM要素を追加または削除する.
2、元素の位置が変わる;
3、元素のサイズ変更(余白、充填、外枠の幅、幅、高さなどの属性が変わるため);
4、コンテンツの変更、例えば、テキストの変更または画像は他の異なるサイズで代替される.
5、最初のページのレンダリング;
6、ブラウザウィンドウのサイズ変更.
変更された性質に応じて、ツリー上または大きなまたは小さい部分をレンダリングするには、再計算が必要です.いくつかの変更は、ページ全体をリメイクすることをもたらすことができます.例えば、スクロールバーが現れたとき.
計算量は毎回の再配置に関係しているので、大部分のブラウザは隊列化によって修正され、再配置プロセスを最適化することを大量に表示します.しかし、強制的に更新することができますが、すべての計画が変更された部分はすぐに適用されます.レイアウト情報の取得動作は、次のような方法を使用することを意味して、キューの更新動作をもたらします.
• offset Top,offset Left,offset Width,offset Height
•scrollTop、scrollLeft、scrollwidth、scrollHeight
•clientTop、clientLeft、clientWidth、clientHeight
•get ComputatidStyle()(currentStyle in IE)(IEではこの関数をcurrentStyleと呼びます)
レイアウト情報はこれらの属性と方法で最新のデータを返しますので、ブラウザはレンダリングキューの中で変更すべき項目を実行して再レイアウトして正しい値を返します.
二、再絵と再組み版を最小化する
ここでは3つのスタイル特性を変え,毎回の変化は元素の幾何学的性質に影響を与える.この悪い例では、ブラウザのレイアウトを3回やり直した.多くの近代的なブラウザーはこのような状況を最適化して一回だけ再配置しますが、旧式のブラウザーの中で、あるいは同時に分離した同期プロセス(例えばタイマーを使っています)があります.効率は非常に低いです.このコードが実行されている間に他のコードがレイアウト情報を照会すると、3つの再レイアウトが発生します.また、このコードはDOMに4回アクセスし、最適化することができます. 同じ効果を達成して効率的にする方法は、すべての変更をまとめて実行し、DOMを一回だけ変更することです.cssText属性を使用することにより実現できます.
もう一つの方法はインラインスタイルコードを修正する代わりに、CSSのクラス名を変更することです.この方法はそれらのスタイルが運転ロジックに依存せず,計算を必要としない場合に適している.CSSクラスの名称を変更すると、より明確になり、メンテナンスしやすくなります.スクリプトの表示コードを免除するのに役立ちますが、クラスを変更するときは、カスケード表を確認する必要がありますので、わずかな性能衝撃を与えるかもしれません.
三、一括修正DOM
DOM元素を何回も修正する必要がある場合、以下の手順で描き直しと並べ替えの回数を減らすことができます.
1、文書ストリームから要素を削除します.
2、複数の変更を適用する.
3、要素をドキュメントに持ち帰る.
このプロセスは二回の再配置を引き起こします.第一歩は一回を引き起こし、第三歩は一回を誘発します.この二つのステップを無視すれば、第二のステップで毎回変更するたびに再配置が開始されます.
3つの基本的な方法は、DOMをドキュメントから取り除くことができる.
1、要素を隠して、修正してから表示します.
2、ドキュメントの断片を使用して、既存のDOM以外にサブツリーを作成し、ドキュメントにコピーします.
3、元の要素をドキュメントから離れたノードにコピーし、コピーを修正し、元の要素を上書きします.
ドキュメントオブジェクトモデル(DOM)は、言語とは独立して、XMLとHTMLドキュメントを使って動作するアプリケーションインターフェース(API)です.ブラウザでは、主にHTMLドキュメントと接触し、WebアプリケーションでXMLドキュメントを検索することもよくあります.DOM APIは主にこれらの文書のデータにアクセスするために用いられる.DOMは言語とは無関係なAPIであるが、ブラウザ内のインターフェースはJavaScriptで実現される.クライアントのほとんどのスクリプトプログラムは、ドキュメントとのつきあいで、DOMはJavaScriptコードの日常的な行動の中で重要な構成部分となります.
一、再絵と再組み版
ブラウザがすべてのページHTMLタグをロードし終わったら、JavaScript、CSSの後、ファイルを解析して二つの内部データ構造を作成します. 一本のDOMツリーはページ構造を表します.レンダリングツリーはDOMノードがどのように表示するかを示しています.レンダリングエンジンはまずHTMLドキュメントを解析して、DOMツリーに変換します.これは第一歩です.次にインライン式であれ、インライン式であれ、インライン式であれ、導入されたCSSスタイルであれば、他のDOMツリーをレンダリングするためのツリー・レンダリングツリーをレンダリングし、レンダリングツリーは、色、サイズなどの表示属性を持つ矩形を含み、これらの矩形の順序は表示順と一致する.レンダリングツリーには、各表示が必要なDOMツリーノードのために、少なくとも1つのノードが格納される(レンダリングツリーにはDOM要素が隠れている).ツリー上のノードを「枠」または「箱」と呼び、CSSモデルの定義に符合し、ページ要素を充填、エッジ、枠と位置を有するボックスと見なす.DOMツリーとレンダリングツリーの構造が完了すると、ブラウザはページ上の要素を表示(描画)することができます.
DOMが要素の幾何学的属性(幅と高さ)に影響を与えるように変化すると、外枠幅や段落にテキストを追加するなど、一連の後続動作が起こる.ブラウザは要素の幾何学的属性を再計算する必要があり、他の要素の幾何学的属性や位置もそのために変更される.ブラウザは、レンダリングツリーに影響を与えた部分を無効にし、レンダリングツリーを再構築する.このプロセスはリメイクと呼ばれています.再レイアウトが完了すると、ブラウザは再描画中に画面に影響を受けた部分を再描画します.
すべてのDOM変化が幾何学的性質に影響するというわけではない.例えば、要素の背景色を変えることは、幅や高さに影響を与えません.この場合、リメイクだけが必要です.要素のレイアウトは変わりません. リメイクとリメイクは重い操作を負担しており、Webアプリケーションのユーザーインターフェースが応答を失う可能性があります.では、リメイクはいつ発生しますか?
1、可視DOM要素を追加または削除する.
2、元素の位置が変わる;
3、元素のサイズ変更(余白、充填、外枠の幅、幅、高さなどの属性が変わるため);
4、コンテンツの変更、例えば、テキストの変更または画像は他の異なるサイズで代替される.
5、最初のページのレンダリング;
6、ブラウザウィンドウのサイズ変更.
変更された性質に応じて、ツリー上または大きなまたは小さい部分をレンダリングするには、再計算が必要です.いくつかの変更は、ページ全体をリメイクすることをもたらすことができます.例えば、スクロールバーが現れたとき.
計算量は毎回の再配置に関係しているので、大部分のブラウザは隊列化によって修正され、再配置プロセスを最適化することを大量に表示します.しかし、強制的に更新することができますが、すべての計画が変更された部分はすぐに適用されます.レイアウト情報の取得動作は、次のような方法を使用することを意味して、キューの更新動作をもたらします.
• offset Top,offset Left,offset Width,offset Height
•scrollTop、scrollLeft、scrollwidth、scrollHeight
•clientTop、clientLeft、clientWidth、clientHeight
•get ComputatidStyle()(currentStyle in IE)(IEではこの関数をcurrentStyleと呼びます)
レイアウト情報はこれらの属性と方法で最新のデータを返しますので、ブラウザはレンダリングキューの中で変更すべき項目を実行して再レイアウトして正しい値を返します.
二、再絵と再組み版を最小化する
var el = document.getElementById('mydiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
ここでは3つのスタイル特性を変え,毎回の変化は元素の幾何学的性質に影響を与える.この悪い例では、ブラウザのレイアウトを3回やり直した.多くの近代的なブラウザーはこのような状況を最適化して一回だけ再配置しますが、旧式のブラウザーの中で、あるいは同時に分離した同期プロセス(例えばタイマーを使っています)があります.効率は非常に低いです.このコードが実行されている間に他のコードがレイアウト情報を照会すると、3つの再レイアウトが発生します.また、このコードはDOMに4回アクセスし、最適化することができます. 同じ効果を達成して効率的にする方法は、すべての変更をまとめて実行し、DOMを一回だけ変更することです.cssText属性を使用することにより実現できます.
var el = document.getElementById('mydiv');
el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
もう一つの方法はインラインスタイルコードを修正する代わりに、CSSのクラス名を変更することです.この方法はそれらのスタイルが運転ロジックに依存せず,計算を必要としない場合に適している.CSSクラスの名称を変更すると、より明確になり、メンテナンスしやすくなります.スクリプトの表示コードを免除するのに役立ちますが、クラスを変更するときは、カスケード表を確認する必要がありますので、わずかな性能衝撃を与えるかもしれません.
var el = document.getElementById('mydiv');
el.className = 'active';
三、一括修正DOM
DOM元素を何回も修正する必要がある場合、以下の手順で描き直しと並べ替えの回数を減らすことができます.
1、文書ストリームから要素を削除します.
2、複数の変更を適用する.
3、要素をドキュメントに持ち帰る.
このプロセスは二回の再配置を引き起こします.第一歩は一回を引き起こし、第三歩は一回を誘発します.この二つのステップを無視すれば、第二のステップで毎回変更するたびに再配置が開始されます.
3つの基本的な方法は、DOMをドキュメントから取り除くことができる.
1、要素を隠して、修正してから表示します.
var ul = document.getElementById('mylist');
ul.style.display = 'none';
appendDataToElement(ul, data);
ul.style.display = 'block';
2、ドキュメントの断片を使用して、既存のDOM以外にサブツリーを作成し、ドキュメントにコピーします.
var fragment = document.createDocumentFragment();
appendDataToElement(fragment, data);
document.getElementById('mylist').appendChild(fragment);
3、元の要素をドキュメントから離れたノードにコピーし、コピーを修正し、元の要素を上書きします.
var old = document.getElementById('mylist');
var clone = old.cloneNode(true);
appendDataToElement(clone, data);
old.parentNode.replaceChild(clone, old);
ps:以上の内容は「高性能javascriptプログラミング」にまとめられています.