Reactについて理解する

Cover Image for Reactについて理解する

(公開・更新)

Reactのレンダリングについて、公式ドキュメントをもとに整理したメモです。 レンダリングの仕組みからCSR・SSR・SSG・ISRの各方式まで、理解した内容をまとめています。

Reactのレンダリングとは?

参考:React公式 - Render and Commit

"Rendering" is React calling your components.

「コンポーネントをReactが呼び出すこと」

ReactがコンポーネントをDOMに反映させるための情報を読み込む処理を指します。 呼び出すだけなのでDOMには反映しません。

Reactの画面表示プロセス

公式ドキュメントによると、画面表示は以下の3ステップで行われます。

  1. Triggering a render(レンダリングのトリガー)
  2. Rendering the component(コンポーネントのレンダリング)
  3. Committing to the DOM(DOMへのコミット)

1. Triggering a render

レンダリングが発生するきっかけです。トリガーは2種類あります。

  • 初期レンダリング:アプリ起動時
  • 再レンダリング:stateやpropsの変更時

Reactはどのコンポーネントを描画すれば良いか判断するために、まずこのきっかけが必要です。

2. Rendering the component

After you trigger a render, React calls your components to figure out what to display on screen.

DOMへの反映はまだ行いません。ここではレンダリング間の diff(差分)があるかどうか を調査します。

  • 初期レンダリング時:ルートコンポーネントを呼び出す
  • 再レンダリング時:トリガーした関数コンポーネントを呼び出す

3. Committing to the DOM

After rendering (calling) your components, React will modify the DOM.

そしてDOMに反映されます。ここで重要なのが以下の一文です。

React only changes the DOM nodes if there's a difference between renders.

Reactは、レンダリング間に差分がある場合にのみDOMノードを変更します。

前回と今回のレンダリング結果を比較し、差分があった時だけDOMを変更します。 差分がなければコミットは行われません。

その後、ブラウザが変更されたDOMを画面に描画します。これがいわゆる ブラウザレンダリング です。

まとめ:レンダリングとは?

レンダリングはDOMへの反映工程の一部ではありますが、差分がなければコミットは行わないため、DOMへの反映が起こらないこともあります。

「レンダリング = commitするか判断するため、diff(差分)を計算すること」

DOM反映の準備工程を指しているのです。

function App() {
  const [count, setCount] = useState(0);

  return <h1>{count}</h1>;
}

// DOMの更新あり(差分がある場合)
// 1回目のレンダリング結果
<h1>0</h1>
// 2回目のレンダリング結果
<h1>1</h1>

// DOMの更新なし(差分がない場合)
// 1回目のレンダリング結果
<h1>0</h1>
// 2回目のレンダリング結果
<h1>0</h1>
// → 差分がないためDOMは更新されない(パフォーマンスの最適化)

DOMと仮想DOM

Reactは 仮想DOM(Virtual DOM) という概念を使っています。

  • 仮想DOMとは、実際のDOMをJavaScriptオブジェクトとして表現したものです
  • Reactはレンダリング時に仮想DOMを生成し、前回の仮想DOMと比較(diff計算)します
  • 差分があった箇所だけ実際のDOMに反映することで、不要なDOM操作を減らしパフォーマンスを最適化します
状態 結果
DOM: A / 仮想DOM: A 差分なし → DOMの変更なし(レンダリングは実行されている)
DOM: A / 仮想DOM: B 差分あり → DOMを変更

Reactのレンダリング方式

Reactアプリのレンダリング方式は主に4種類あります。

方式 特徴 向いているケース
CSR ブラウザ側でレンダリング インタラクションが多いSPA
SSR サーバー側でHTMLを生成 動的コンテンツが多いサービス
SSG ビルド時にHTMLを生成 静的コンテンツ中心のサイト
ISR SSGに定期的な再生成を追加 大規模サイトや定期更新コンテンツ

CSR(クライアントサイドレンダリング)

JavaScriptによってブラウザ側でレンダリングする方法です。

  • 初期ロードでは空のHTMLを受け取り、JavaScriptで動的にコンテンツを生成
  • 初期表示は遅いが、その後の画面遷移は高速
  • SPAの基本的なレンダリング方式
  • SEO面で不利
  • ユーザーの端末スペックに依存してしまう

SSR(サーバーサイドレンダリング)

サーバー側で処理し、HTMLを構築してクライアントに返す方式です。

  • ハイスペックなサーバーでHTMLを構築できるため端末スペックに依存しない
  • 初期表示が早く、SEOに有利
  • リクエストごとにサーバーで処理するためサーバー負荷が高い
  • Next.jsなどのフレームワークで実現可能

SSG(静的サイトジェネレーション)

ビルド時にHTMLを構築しておく方式です。

  • ビルド時に外部APIからデータも取得し、HTMLを事前生成
  • ユーザーからリクエスト時に事前生成済みのHTMLを返す
  • CDNにキャッシュしておくことで高速な表示が可能
  • コンテンツの更新には再ビルドが必要

SSGの課題

  1. 大量ページのビルドに時間がかかる → フォールバックで対応
  2. 頻繁に更新されるコンテンツには不向き → ISRで対応

ISR(Incremental Static Regeneration)

SSGをベースに、ページごとに更新間隔を設定できる方式です。定期的にバックグラウンドで再生成を行います。

export async function getStaticProps() {
  return {
    props: { data },
    revalidate: 60, // 60秒ごとに再生成
  };
}
  • SSGの利点(高速表示・サーバー負荷軽減)を維持しながらデータ更新も可能
  • 大規模サイトや定期的な更新が必要なコンテンツに適している
  • 設定した更新間隔までは古いデータが表示される可能性あり(リアルタイム性は低い)
  • Next.js特有の機能のため、他のフレームワークでは利用できない場合がある