Web ページをレンダリングするブラウザの処理フローチャート:
具体的な処理手順:
1. ブラウザは、取得した HTML コードを DOM ツリーに解析し、HTML 内の各タグ ( tag ) は DOM ツリー内のすべてのノードであり、ルート ノードは一般的に使用されるドキュメント オブジェクトです。 DOM ツリーには、display:none 非表示を含むすべての HTML タグと、JS を使用して動的に追加された要素が含まれます。たとえば、IE では -moz で始まるスタイルが削除され、Firefox では
で始まるスタイルが削除されます。 3. レンダー ツリーは DOM ツリーとスタイルを組み合わせて構築されます。レンダー ツリーは DOM ツリーに似ていますが、その違いは非常に大きく、レンダー ツリーの各ノードは独自のスタイルを識別でき、レンダー ツリーには非表示のノード (表示など) が含まれません。 :none ノード、およびヘッド ノード)。これらのノードはレンダリングに使用されず、レンダリングに影響を与えないためです。注: Visibility:hidden がレイアウトに影響を与え、スペースを占有するため、visibility:hidden で非表示にされた要素はレンダー ツリーに引き続き含まれます。 CSS2 標準によれば、レンダー ツリー内の各ノードはボックス (ボックス次元) と呼ばれ、ページ要素はパディング、マージン、境界線、および位置を備えたボックスであると理解されます。
4. レンダー ツリーが構築されると、ブラウザはレンダー ツリーに基づいてページを描画できます。
再描画
再描画は、可視性、輪郭、背景色の属性の変更など、要素の外観の変更によってトリガーされるブラウザーの動作です。ブラウザは新しい属性に基づいて要素を再描画し、要素に新しい外観を与えます。
Reflow
Reflow はより明白な変更であり、レンダー ツリーを再計算する必要があると理解できます。すべてのページは少なくとも 1 回、ページの読み込み時にリフローする必要があります。
注: リフローは確実に再描画を引き起こしますが、再描画は必ずしもリフローを引き起こすとは限りません。リフローのトリガー
2. フォントの変更
4. ユーザーが入力ボックスにテキストを入力する。
5. hover (IE の兄弟擬似ノード) などの CSS 擬似クラスのアクティブ化 (IE では、silibing の擬似クラスのアクティブ化)。7. DOM のスクリプト操作 (DOM を操作するスクリプト)
8. offsetWidth および offsetHeight 属性の値を設定します。 style 属性のプロパティ)。
リフローと再描画を減らす方法
1. スタイルが動的に変更される場合は、cssText を使用します (最適化されていないブラウザーを考慮してください) 2. 操作された要素を「オフライン」で処理します。処理後に 1 回更新されます。
キャッシュ操作に DocumentFragment を使用し、1 つのリフローと再描画をトリガーします。
cloneNode (true または false) を使用して、replaceChild テクノロジーをトリガーします。リフローと再描画。
3. ブラウザがキューをフラッシュする原因となる属性に頻繁にアクセスしないでください。確実にキャッシュしたい場合は、キャッシュを使用してください。リフロー レンダー ツリーのサイズ
// 不好的写法 var left = 1; var top = 1; el.style.left = left + "px"; el.style.top = top + "px";// 比较好的写法 el.className += " className1"; // 比较好的写法 el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
5. DOM ツリーの末尾のクラスをできるだけ変更します (リフローの範囲を制限するため)。外部クラスのスタイルはリフローを 1 つだけ生成します);
7 .アニメーション効果は、位置属性が絶対または固定である要素に適用されます (アニメーション効果は、位置属性が絶対または固定である要素に適用されます)。他の要素のレイアウトを変更するため、完全なリフローではなく、再描画が発生するだけです。これにより、コストが低くなります);8. 速度のために滑らかさを犠牲にすることも推奨しています。つまり、移動することをお勧めします。ただし、このアニメーションが次のリフローの場合、CPU が 100% 使用され、ブラウザがリフローの更新に苦労するため、アニメーション要素が一度に 3 ピクセルずつ移動すると、アニメーションがぎくしゃくしてしまいます。
9. テーブル データの使用は避けてください (テーブルは小さく、まれであるため、レイアウトが完全に確立されるまでに複数のパスが必要になることがよくあります)。以前に入力した DOM 要素の);
。
10.避免使用css的JavaScript表达式(因为他们每次重新计算文档,或部分文档、回流。正如我们从所有的很多事情看到的:引发回流,它可以每秒产生成千上万次。)。
实例测试一:
测试代码不改变元素的规则,大小,位置。只改变颜色,所以不存在回流,仅测试重绘,代码如下:
<body> <script type="text/javascript"> var s = document.body.style; var computed; if (document.body.currentStyle) { computed = document.body.currentStyle; } else { computed = document.defaultView.getComputedStyle(document.body, ''); } function testOneByOne(){ s.color = 'red';; tmp = computed.backgroundColor; s.color = 'white'; tmp = computed.backgroundImage; s.color = 'green'; tmp = computed.backgroundAttachment; } function testAll() { s.color = 'yellow'; s.color = 'pink'; s.color = 'blue'; tmp = computed.backgroundColor; tmp = computed.backgroundImage; tmp = computed.backgroundAttachment; } </script> color test <br /> <button onclick="testOneByOne()">Test One by One</button> <button onclick="testAll()">Test All</button> </body>
实例测试二:
跟第一次测试的代码很类似,但加上了对layout的改变,为的是测试回流。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1 /DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> </head> <body> <script type="text/javascript"> var s = document.body.style; var computed; if (document.body.currentStyle) { computed = document.body.currentStyle; } else { computed = document.defaultView.getComputedStyle(document.body, ''); } function testOneByOne(){ s.color = 'red'; s.padding = '1px'; tmp = computed.backgroundColor; s.color = 'white'; s.padding = '2px'; tmp = computed.backgroundImage; s.color = 'green'; s.padding = '3px'; tmp = computed.backgroundAttachment; } function testAll() { s.color = 'yellow'; s.padding = '4px'; s.color = 'pink'; s.padding = '5px'; s.color = 'blue'; s.padding = '6px'; tmp = computed.backgroundColor; tmp = computed.backgroundImage; tmp = computed.backgroundAttachment; } </script> color test <br /> <button onclick="testOneByOne()">Test One by One</button> <button onclick="testAll()">Test All</button> </body> </html>
避免回流和重绘的次数可从代码的角度来实现性能优化,因此我们在写代码时应尽量使用上诉方法来减少网页回流和重绘的次数。