3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nextのレンダリング戦略でUXはどれくらい変わる?

Last updated at Posted at 2025-12-09

本記事に関して

Next.jsは レンダリング戦略 を細かく制御できることが強みとされています。ただそれが実際にパフォーマンスやUXにどれほどの影響があるのかがわからなかったため、各レンダリング戦略が体感でき、且つパフォーマンスが計測できるサイトを作ってみました。
サーバーサイドレンダリング (SSR)静的サイト生成 (SSG)クライアントサイドレンダリング (CSR)パーシャル・プリレンダリング (PPR)の4つが比較できるようになっています。
https://next-performance-test-ten.vercel.app/

技術選定と実装内容

技術選定

使用言語・フレームワーク

  • 言語: TypeScript 5
  • フレームワーク: Next.js 15.3.6
  • UIライブラリ: React 19.0.0
  • スタイリング: Tailwind CSS 4
  • 開発環境: Turbopack
  • ホスティング: Vercel

計測ツール

  • Web Vitals: web-vitals 5.0.3
    • 標準のCore Web Vitals(FCP, LCP, TTFB, INP)を計測
  • カスタムメトリクス:
    • TTCV (Time To Content Visible): 最初のカードが表示されるまでの時間
    • ListRendered: リストのDOM描画完了時間
    • FirstImageLoaded: 最初の画像の読み込み完了時間
  • Server-Timing API: サーバーサイドの処理時間を詳細に計測
    • アプリケーション層の処理時間
    • 外部API取得時間

実装内容

リポジトリは以下に公開しています

データフェッチの仕組み

各レンダリング戦略で異なるデータフェッチ方法を採用しています。

1. CSR (Client-Side Rendering)

  • 内部API (/api/posts) 経由でJSONPlaceholder APIからデータを取得
  • クライアントサイドで400msの人工遅延を追加

2. SSR (Server-Side Rendering)

  • 内部API経由でpostsとusersを並列取得
  • サーバーサイドでデータを統合・加工
  • 700msの人工遅延を追加(DB結合や集計処理を模倣)

3. SSG (Static Site Generation)

  • ビルド時にJSONPlaceholder APIから直接データ取得
  • force-staticで静的生成を強制

4. PPR風 (Streaming + Suspense)

  • 静的部分は即座に表示、動的部分はSuspenseでストリーミング
  • 動的コンテンツは600msの遅延後にストリーミング配信

人工遅延の設定

リアルな環境を模倣するため、各箇所に人工的な遅延を追加しています。

エンドポイント/処理 遅延時間 目的
/api/posts 300ms サーバー処理・外部API取得の遅延を模倣
/api/users 150ms 軽量なAPI取得を想定
SSR追加処理 700ms DB結合や複雑な集計処理を模倣
CSRクライアント処理 400ms JS実行・API待ちの体感差を強調
PPR動的部分 600ms 動的コンテンツ取得の遅延を模倣

これらの遅延により、各レンダリング戦略のパフォーマンス特性を明確に比較できるようになっています。

今回はAPIやページの表示内容が軽量のため、人口遅延を入れないと計測結果にほとんど差がでませんでした。つまりは軽量なページであればどの手法でもさほどUXに影響はないです。ただしSEOには影響があるのでご注意ください。

測定結果

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

メトリクス 1回目 (ms) 2回目 (ms) 3回目 (ms) 4回目 (ms) 5回目 (ms) 平均 (ms)
TTFB 44 30 29 40 33 35
FCP 112 192 72 104 112 118
LCP 112 192 72 104 112 118
TTCV 2220 1559 1582 1418 1356 1627
ListRendered 2214 1554 1578 1414 1350 1622
FirstImageLoaded 2225 1554 1578 1408 1345 1622

静的サイト生成 (SSG)

メトリクス 1回目 (ms) 2回目 (ms) 3回目 (ms) 4回目 (ms) 5回目 (ms) 平均 (ms)
TTFB 41 42 36 35 43 39
FCP 124 112 112 148 124 124
LCP 124 112 112 148 124 124
TTCV 45 38 41 40 51 43
ListRendered 40 33 37 36 48 39
FirstImageLoaded 40 33 37 31 42 37

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

メトリクス 1回目 (ms) 2回目 (ms) 3回目 (ms) 4回目 (ms) 5回目 (ms) 平均 (ms)
TTFB 36 35 82 39 34 45
FCP 120 120 164 104 104 122
LCP 120 120 164 104 104 122
TTCV 1304 1275 1340 1383 1346 1330
ListRendered 1300 1270 1337 1378 1343 1326
FirstImageLoaded 1300 1270 1332 1378 1337 1323

パーシャル・プリレンダリング (PPR)

メトリクス 1回目 (ms) 2回目 (ms) 3回目 (ms) 4回目 (ms) 5回目 (ms) 平均 (ms)
TTFB 41 43 35 41 47 41
FCP 116 108 104 120 128 115
LCP 116 108 104 120 128 115
TTCV 1350 1216 1276 1193 1258 1259
ListRendered 1346 1213 1273 1189 1255 1255
FirstImageLoaded 1345 1205 1267 1184 1250 1250

期待される傾向、結果の分析

TTFB (Time To First Byte)

サーバーがリクエストを受け取ってから、レスポンスの最初の1バイトをブラウザに送信するまでの時間です。

期待される傾向

  • SSG (静的生成) と PPR (部分的な事前レンダリング) は、事前にHTMLが生成・キャッシュされるため、非常に短くなる傾向があります。SSR (サーバーサイドレンダリング) と CSR (クライアントサイドレンダリング) は、リクエストごとに処理が走るため、SSG/PPRより長くなります。特にSSRは毎回サーバーでHTMLを生成するため長くなりがちです。

FCP (First Contentful Paint) & LCP (Largest Contentful Paint)

FCP: 画面に最初のコンテンツ(テキスト、画像など)が描画されるまでの時間です。
LCP: 画面内の最大コンテンツ要素(メイン画像や大きなテキストブロック)が描画されるまでの時間です。

期待される傾向:

  • SSG/SSR/PPRは、HTMLにコンテンツが含まれた状態で配信されるため、ブラウザは受け取り次第すぐに描画を開始でき、FCP/LCPが短くなる傾向があります。

  • CSRは、空のHTMLを受け取った後、JavaScriptをダウンロード・実行して初めてコンテンツを生成・描画するため、FCP/LCPが長くなる傾向があります。

TTV (Time To View/Total Time to View) & リスト描画時間

この計測では、「TTCV (Time To Contentful View)」や「ListRendered」「FirstImageLoaded」というカスタムメトリクスが使用されています。これらは、ページが完全に表示され、コンテンツが利用可能になるまでの時間を示す指標です。

期待される傾向:

  • SSR/CSR/PPRは、データフェッチやJavaScriptの処理(ハイドレーションなど)が関与するため、SSGよりも時間がかかる傾向があります。
  • SSGは静的なコンテンツなので、TTCVやListRenderedがFCP/LCPとほぼ同等で、非常に短くなることが期待されます。
  • SSR/CSR/PPRは、FCP/LCPからTTCV/ListRenderedまでの間に、JavaScriptのハイドレーションや動的データのロード時間が発生し、時間の差が生まれる傾向があります。

結果の分析

✅️ 本来出るべき結果が出ている点

  • SSG/PPRのTTFBが最も短い: 静的・キャッシュ可能なコンテンツの高速配信という利点が明確に出ています。
  • SSR/CSR/PPRのTTCV/ListRenderedが長い: FCP/LCPとの間に大きな差があり、初期表示後のJavaScript処理(ハイドレーションなど)に時間がかかっているという動的なレンダリング戦略の一般的なトレードオフが明確に表れています。
  • SSGが最終的なコンテンツ描画(TTCV/ListRendered)で最も速い: 静的なコンテンツは最速であるという基本原則通りです。

⚠️ 意外な点(良好な結果ではある)

  • CSRのFCP/LCPがSSG/SSRとほぼ同等: 通常はCSRが最も遅くなるはずですが、この計測では非常に高速です。これは、計測対象のページが非常にシンプルで、Javascriptのバンドルサイズが小さいからであると考えられます。

感想

SSGが使える場合は積極的に使用すべきで、それが難しい場合はISRを使ってなるべく静的データを作っておくことで表示スピードが高速になりSEO対策にもなると思いました。また、SSRとCSRはレスポンススピードによってUXが左右される傾向があるため、個人的にはPPRが最もストレスフリーだと感じました。Next14以降はPPRはStableになったため積極的に使っていこうと思います。

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?