ReflowとRepaintの理解
DOM操作やスタイルの変更を行う際、ブラウザは画面の表示内容を更新するために内部で レンダリングプロセス を実行します。この中で重要な概念が Reflow(リフロー) と Repaint(リペイント) です。両者を理解することで、パフォーマンスを意識した効率的なコードを書くことができます。
1. Reflow(リフロー)
-
定義: DOMやCSSOMに変更が加わり、要素のサイズ・位置・構造が再計算される処理。
-
発生する例:
-
要素の追加・削除 (
appendChild,removeChild) -
要素のサイズ変更(
width,height,padding,marginなど) -
フォントサイズやウィンドウサイズの変更
-
スクロール発生時のレイアウト再計算
-
-
コスト: 非常に高い。再計算は変更された要素だけでなく、その子要素・親要素や他の依存関係のあるノードにも影響する。
2. Repaint(リペイント)
-
定義: レイアウトの位置・サイズは変わらないが、外観(色や背景、ボーダーなど)が変化したために再描画される処理。
-
発生する例:
-
背景色の変更 (
background-color) -
テキストの色変更 (
color) -
ボーダーの色変更
-
-
コスト: Reflowに比べれば軽いが、それでも頻発するとパフォーマンスに影響する。
3. ReflowとRepaintの関係
-
Reflowが発生すると必ずRepaintも発生する(レイアウト計算後に描画が必要になるため)。
-
Repaintは単独で発生することもある(色や装飾の変更のみの場合)。
4. パフォーマンス最適化のベストプラクティス
-
DOM操作をまとめる
-
繰り返しの操作を避け、まとめて変更する。
-
例:
DocumentFragmentを使って複数の要素を一度に追加する。
-
-
スタイルの変更をまとめる
-
複数のスタイル変更を個別に行うと、そのたびにReflow/Repaintが発生する。
-
解決策:
classList.add()でクラスをまとめて変更。
-
-
レイアウト情報の読み取りに注意
-
offsetWidth,offsetHeight,getComputedStyleなどは強制的に最新のレイアウトを計算させるため、高コスト。 -
必要最小限に抑える。
-
-
アニメーションの最適化
-
レイアウトに影響するプロパティ(
top,left,width,height)の変更はReflowを引き起こす。 -
GPUアクセラレーションが効く
transformやopacityを活用すると、Reflowを避けられRepaintのみで済む。
-
5. 実例(効率の悪いケースと良いケース)
悪い例(毎回Reflow発生):
良い例(Reflowをまとめる):
まとめ
-
Reflow: レイアウト再計算(高コスト)
-
Repaint: 見た目の再描画(中コスト)
-
最適化の鍵: DOM操作やスタイル変更をまとめる、レイアウト情報の読み取りを最小化する、アニメーションには
transformやopacityを活用する。
ChatGPT5 生成日:2025/09/11