リフロウとリペイント:CSSがjavascriptのパフォーマンスの足をひっぱっている?(を読んだメモ)
Stubbornella ? Blog Archive ? Reflows & Repaints: CSS Performance making your JavaScript slow?
上記エントリをテキトーに解釈して要点をメモってみた。
リペイント(repaint)
要素のスキン見た目、が変化したときに発生。
ただしレイアウトには影響しない。
- outline
- visibility
- background color
など、
Operaのレポートによると、リペイントは処理コストが高くつくらしい。
なぜなら、DOMツリー内の他のノード(要素)全ての見た目について検証しなければいけないから。
リフロウ(reflow)
リフロウはパフォーマンスにとってさらに重要。
なぜなら、それによってページの一部(あるいは全体)のレイアウトの変更を引き起こすから。
たとえば、下のようなHTMLがあったとした場合、
<body> <div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol> </div> </body>
<p>要素の変更はその子要素であるの<strong>要素のリフロウを引き起こす。
また、ブラウザによってはその祖先要素である<div>や<body>のリフロウを引き起こす場合もある。
さらに、後続の要素である<h5><ol>要素のリフロウも引き起こす。
このように、リフロウの連鎖によってページ全体の再描画を引き起こしパフォーマンスが低下する。
リフロウを引き起こす原因
困ったことに、たくあんある orz
リフロウを避けるあるいはその影響を最小化する方法
可能な限り末端に近いほうのノードで変更する
そうすることによって、リフロウの影響範囲を限定することができる
styleプロパティによる変更を避ける
styleのプロパティ1つ1つに対する変更に対してリフロウが発生する。
その代わりに、classを別途用意してclassの切り替えとすることで、1度のリフロウで済ませることができる。
アニメーションは position fixed または absolute の要素で
positionがfixedまたは、absoluteの要素の要素は他の要素のレイアウトに影響を与えない。リペイントは発生するが、リフロウに比べたらコストは低い。
レイアウト目的でのtableの使用を避ける(または table-layout を fixed に設定する)
テーブル全体のレイアウトはテーブルの最後の行を表示するまで確定できない。
例えば最後の行のセルの幅がそれ以前の行の幅より大きくなったとしたら、テーブル全体の幅が変更されてしまう。
そのため、テーブルのレンダリングはコストが高い。
それがテーブルをレイアウト目的で使ってはいけない理由。
テーブルを使う場合には、table-layout を fixed に設定した方がよい。
それによって、ブラウザは最後までテーブルの要素を読み込まなくても、レイアウトを確定することができる。
CSS内でのjavascript式の使用を避ける(IEのみ)
css内での式の利用は非常にコストが高い。
それはリフロウのたびに式の評価が必要になるから。そしてその評価の結果がリフロウを発生させ、それにともなって式の評価を行い... と連鎖する。
CSSでjavascripの式をつかっちゃダメ、ゼッタイ。
以上、
テキトーなんで注意。
ちゃんと理解したい人は原文を読むことをお勧めします。
参考になりそうなリンク
上記エントリから参考になりそうなリンクをピックアップ
stubbornella's reflow Bookmarks on Delicious
Efficient JavaScript - Opera Developer Community
Notes on HTML Reflow