Reactについて理解する

(公開・更新)
Reactのレンダリングについて、公式ドキュメントをもとに整理したメモです。 レンダリングの仕組みからCSR・SSR・SSG・ISRの各方式まで、理解した内容をまとめています。
Reactのレンダリングとは?
参考:React公式 - Render and Commit
"Rendering" is React calling your components.
「コンポーネントをReactが呼び出すこと」
ReactがコンポーネントをDOMに反映させるための情報を読み込む処理を指します。 呼び出すだけなのでDOMには反映しません。
Reactの画面表示プロセス
公式ドキュメントによると、画面表示は以下の3ステップで行われます。
- Triggering a render(レンダリングのトリガー)
- Rendering the component(コンポーネントのレンダリング)
- 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の課題
- 大量ページのビルドに時間がかかる → フォールバックで対応
- 頻繁に更新されるコンテンツには不向き → ISRで対応
ISR(Incremental Static Regeneration)
SSGをベースに、ページごとに更新間隔を設定できる方式です。定期的にバックグラウンドで再生成を行います。
export async function getStaticProps() {
return {
props: { data },
revalidate: 60, // 60秒ごとに再生成
};
}
- SSGの利点(高速表示・サーバー負荷軽減)を維持しながらデータ更新も可能
- 大規模サイトや定期的な更新が必要なコンテンツに適している
- 設定した更新間隔までは古いデータが表示される可能性あり(リアルタイム性は低い)
- Next.js特有の機能のため、他のフレームワークでは利用できない場合がある
