10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Frontend Performance - Part 1] ブラウザの描画処理を理解する(Rendering Pipeline入門)

10
Posted at

ChatGPT Image Apr 21, 2026, 11_04_48 AM.png


📝 注意
本記事はAIの補助を受けて編集しています。
内容は大規模Webアプリケーションの実務経験に基づいています。


目次

  1. 問題提起 – 最適化しているのに遅い?
  2. よくある悪い例 – 原因が分からないUIの遅さ
  3. 正しいアプローチ – ブラウザのパイプラインを理解する
  4. イメージで理解 – HTMLからピクセルまでの流れ
  5. 実践 – DevToolsで「見える化」する
  6. チェックリスト – 今すぐできる改善
  7. まとめ & 次回予告

1. 問題提起 – 最適化しているのに遅い?

こんな経験はありませんか?

  • memouseMemouseCallback を多用しているのにUIがカクつく
  • APIは速いのに、画面の表示が遅い
  • ちょっとしたstyle変更で全体が重くなる理由が分からない

ここで重要なのは:

問題はReactでも、純粋なJavaScriptでもありません。

本質的な原因は、

👉 ブラウザがどのようにUIを描画しているかを理解していないこと

です。

Rendering Pipelineを理解していないと:

  • 最適化する場所を間違える
  • 指標の見方を誤る
  • むしろパフォーマンスを悪化させる

可能性すらあります。


2. よくある悪い例 – 原因が分からないUIの遅さ

一見問題なさそうなコードを見てみましょう。

<ul id="list"></ul>
const list = document.getElementById("list");

for (let i = 0; i < 1000; i++) {
  const li = document.createElement("li");
  li.innerText = `Item ${i}`;
  list.appendChild(li);
}

これは問題なく動作します。

しかし、次のような処理を追加すると:

li.style.color = i % 2 === 0 ? "red" : "blue";

さらに悪いケース:

list.style.width = `${i}px`;

👉 UIが目に見えて遅くなります。

❌ なぜ遅くなるのか?

  • ループが原因ではない
  • DOM APIが遅いわけでもない

原因は:

レイアウト計算(reflow)を何度も強制していること

styleを変更するたびに、ブラウザはレイアウトを再計算し、
結果的にパイプライン全体が何度も実行されます。


3. 正しいアプローチ – ブラウザのパイプラインを理解する

ブラウザは、DOMを変更した瞬間に描画するわけではありません。

以下のステップを順番に処理します:

ステップ 内容
1. HTML解析 DOMツリーを構築
2. CSS解析 CSSOMツリーを構築
3. Render Tree DOM + CSSOMを結合し、描画対象を決定
4. Layout 位置・サイズを計算(reflow)
5. Paint 色やテキストを描画
6. Composite レイヤーを合成して最終表示

🔥 重要なポイント

すべての変更が同じコストではない

操作例 発生する処理 コスト
color, background Paint + Composite
width, height Layout + Paint + Composite
transform, opacity Compositeのみ 非常に低い

👉 これが「transformの方が滑らか」と言われる理由です。


4. イメージで理解 – HTMLからピクセルまで

描画の流れは次のように考えると分かりやすいです:

HTML  ──┐
       ├──► DOM ──┐
CSS  ──┘          ├──► Render Tree ──► Layout ──► Paint ──► Composite ──► 画面表示

具体例

element.style.width = "200px";

この1行の裏では:

  1. Layoutが無効化される
  2. 位置・サイズを再計算
  3. Paintを再実行
  4. Compositeして画面に反映

👉 わずかな変更でも、数十msのコストが発生することがあります。


5. 実践 – DevToolsで「見える化」する

パフォーマンスは「感覚」ではなく「計測」です。

手順

  1. Chrome DevTools → Performanceタブ
  2. Record(●) をクリック
  3. 操作(スクロール、クリックなど)を実行
  4. 停止して結果を確認

見るべきポイント

  • Layout(紫):レイアウト計算
  • Paint(緑):再描画
  • Script(黄色):JavaScript実行

🎯 チェックすべきこと

  • Layoutが何度も発生していないか?
  • **Long Task(50ms以上)**はないか?
  • 同じ領域でPaintが繰り返されていないか?

💡 原則:推測ではなく計測すること


6. チェックリスト – 今すぐできる改善

この記事を読んだら、まず以下を試してください:

  • DevToolsで実際の操作を記録し、Layoutの発生回数を確認する
  • width / height / top / lefttransform に置き換えられないか検討する
  • ループ内での「読み取り + 書き込み」を避ける

改善例

// ❌ 悪い例
for (let i = 0; i < items.length; i++) {
  items[i].style.width = i * 10 + "px";
  const height = items[i].offsetHeight; // layout強制
}
// ✅ 改善例
const widths = [];
for (let i = 0; i < items.length; i++) {
  widths.push(i * 10 + "px");
}

for (let i = 0; i < items.length; i++) {
  items[i].style.width = widths[i];
}
// 読み取りと書き込みを分離

7. まとめ & 次回予告

🧠 押さえておくべきポイント

  1. ブラウザは段階的なパイプラインで描画している
  2. 操作によってコストは大きく異なる
  3. パフォーマンスとは「ブラウザの仕事を減らすこと」

👉 次回予告
[Frontend Performance - Part 2] Reflow / Repaint / Compositeの違いとは?ブラウザが重くなる瞬間を理解する)

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?