Curated Tech Reading Map

次に読むべき技術書が見つかるサイト

ブログ記事

App Router の「なぜ」を掘り下げる──『実践Next.js』が解説する Server Components・キャッシュ・Server Actions

著者: DevBookPath 編集部公開日: 更新日:

Next.js の App Router への移行は、ルーティング記法が変わるだけではない。コンポーネントをどこで実行するかという根本的な設計の考え方が変わる。この転換を理解しないまま移行すると、キャッシュの意図しない動作や、Server/Client Component の誤った配置で詰まることになる。

吉井健文著『実践Next.js App Routerで進化するWebアプリ開発』(技術評論社、2024年)は、公式ドキュメントでは補いきれない App Router の設計原理を、実際のアプリケーション開発を通じて解説する。

1. Server Components が変えるハイドレーションの考え方

従来の SSR では、サーバー側で生成した HTML をブラウザに送信した後、JavaScript を読み込んでインタラクティブな動作を付与する「ハイドレーション」が必要だった。この処理はデバイスの CPU を消費し、ページの操作可能になるまでの時間を遅らせる要因だった。

React Server Components(RSC)は、サーバー側のみで実行が完結するコンポーネントを分離することでこの問題に対処する。データの取得や HTML の生成をサーバーで行い、JavaScript バンドルをブラウザに一切送らない。動的な操作が必要な部分だけを 'use client' で Client Component として指定する。

この分離によって、必要な JavaScript の量を絞り込める。本書は、どのコンポーネントを Server Component にするかの判断基準と、Server/Client Component を組み合わせた設計パターンをコードで示す。

flowchart LR
    subgraph SC["Server Component(デフォルト)"]
        D["DB・API アクセス"] --> H["HTML 生成"]
        H -->|"JS バンドルを送らない"| BR["ブラウザ"]
    end
    subgraph CC["'use client' を付けた部分"]
        ST["useState / useEffect"] --> INT["インタラクション\n(クリック・入力)"]
    end
    BR --> CC
    style SC fill:#e8f4fd,stroke:#4a9eda
    style CC fill:#e8f8e8,stroke:#4caf50

2. App Router の多層キャッシュと、意図した無効化

App Router の難所のひとつが、Request のメモ化・データキャッシュ・Full Route キャッシュ・Router キャッシュという 4 つのキャッシュレイヤーの挙動だ。Next.js v14 時点では多くのキャッシュがデフォルトで有効化されており、古いデータが残り続けたり、個人情報が意図せず共有されたりするリスクがあった(v15 でデフォルトの一部が変更された)。

本書はこれらのキャッシュがそれぞれどのタイミングで有効になり、何がトリガーで無効化されるかを整理する。タグを使ったオンデマンドの再検証(revalidateTag)など、きめ細かいキャッシュ制御の実装方法も扱う。

キャッシュを適切にコントロールするには、まずどのレイヤーで何がキャッシュされているかを理解することから始まる。本書はその構造を説明した上で、実装例を示す。

3. Server Actions と Progressive Enhancement の設計

Server Actions は、サーバーサイドの関数をフォームやクライアントコードから直接呼び出せる機能だ。REST API のエンドポイントを別途定義せずにデータの送受信ができる。

本書はこれを「API が不要になる便利な機能」としてではなく、JavaScript の読み込みが遅れている環境でも基本動作を保証する「Progressive Enhancement」の思想から位置づける。フォームが Server Action と連携していれば、JavaScript なしでも送信が機能する。

useOptimistic を使ったネットワーク待ちを感じさせない UI 更新や、バリデーションとエラーメッセージの実装方法も解説されている。Prisma によるデータ操作や NextAuth.js を使った認証の実装も含む、本番を想定した構成でコードが示される。

4. この本が効く場面

「更新したはずのデータが画面に残り続ける」「検索で見つけた no-store を付けたら直ったが、なぜ直ったのかは説明できない」——App Router のキャッシュ起因の詰まりは、4 つのレイヤーのどれが効いているかを切り分けないまま対処していることが原因になりやすい。本書でレイヤーごとの有効化・無効化の条件を押さえると、対処の起点が「場当たりの検索」から「効いているレイヤーの特定」に変わる。

生成 AI に App Router のコードを書かせている場合にも効く。動くコードは得られても、キャッシュの安全性や Server/Client の境界設計が妥当かを判断する軸が自分になければ、出力の良し悪しを評価できない。フレームワークの根本挙動から理解することで、AI の出力を監査する側に回れる。

5. 向いている人・向いていない人

向いている人

  • Pages Router での開発・運用経験はあるが、4 層キャッシュや Server Actions の挙動を自分の言葉で説明できず、App Router への移行設計に踏み切れない
  • React の基本実装はできるものの、認証・データベース・デプロイまで含めた一つのアプリを Next.js で通しで組んだ経験がない
  • AI が生成した Next.js コードを、キャッシュやレンダリングの原理に照らして監査する立場にある

向いていない人

  • React のコンポーネントやフックをこれから学ぶ人(本書は React 習得済みが前提。先に『Reactハンズオンラーニング 第2版』のような基礎書から入る方が結果的に早い)
  • 手順を一つずつなぞって組み上げるハンズオン形式を期待する人(本書は完成済みのサンプルリポジトリを読み解きながら進む構成で、段階的なチュートリアルではない)

6. Next.js 15 との差分にどう向き合うか

本書が対象とするのは v13/v14 で、v15 ではキャッシュのデフォルトが「有効」から「無効」へ大きく転換された。fetch リクエストは force-cache から no-store へ、GET の Route Handler は静的キャッシュから動的レンダリングへ、Client Router Cache のページ単位キャッシュは 30 秒から 0 秒へ変わっている。本書のコード例の一部は、最新バージョンでは明示的に設定を書かないと同じ挙動を再現しない。

それでも 4 層構造の解説の価値は残る。デフォルトで効かなくなった分、キャッシュを効かせたい箇所では開発者がレイヤーを選んで明示的に設計する必要が生まれたからだ。どのレイヤーで何がキャッシュされ、何をトリガーに破棄されるかという本書の中心的な整理は、明示的設計が前提の v15 以降でこそ必要になる。手元の Next.js のバージョンで公式ドキュメントのデフォルト値を照合しながら読むのが実際的だ。

7. 読み方ガイド——原理の前半、実装の後半

全 11 章・368 ページは二部に分かれる。第1〜5章が RSC・レンダリング・データフェッチといった原理の解説、第6章以降が写真投稿 SNS を題材にしたアプリケーション開発編だ。後半は認証と認可(第8章)、投稿機能(第9章)、画像のアップロード(第10章)、デプロイ・運用環境の構築(第11章)と、本番を想定した構成で進む。

App Router の挙動を理解し直すことが目的なら、まず第1〜5章を精読する。後半を手を動かしながら進める場合は注意が一つある。サンプルコードはモノレポ構成のため、開発用ポートの重複や Prisma schema の上書きといった環境構築段階での躓きが報告されている。環境で手間取っても、本文の設計解説の価値とは切り分けて読み進めたい。

8. 読後の次の一歩

App Router のキャッシュ制御を突き詰めると、関心はその下にある HTTP のキャッシュや URI 設計という Web 標準の層へ降りていく。次の一冊には『Webを支える技術』が合う。フレームワークが隠している HTTP・キャッシュ・URI の土台を固めると、Next.js の挙動を「フレームワークの仕様」としてではなく Web の原理から説明できるようになる。

実務での最初の一歩は、いま関わっているプロジェクトのページを一つ選び、データ取得箇所ごとに 4 つのキャッシュレイヤーのどれが効いているかを書き出してみることだ。本書の整理は、自分のコードに当てはめて確かめると定着する。

筆者の体験から

新規プロジェクトでApp Router採用を検討していた頃、Pages Routerの経験から「書き方が変わるだけ」と軽く見ていた。検証画面で更新したはずのデータが残り続ける現象にぶつかり、fetchにno-storeを付けて直したが、なぜ直ったのか自分の言葉で説明できなかった。

読んだあとは、まずどのキャッシュレイヤーが効いているかを切り分けてから対処する順番に変わり、revalidateTagでタグ単位に再検証する設計へ切り替えた。ただし本書が前提とするv13/v14とは異なり、手元のv15では挙動が一致せず、バージョンを確認し公式ドキュメントと照合し直す作業が必要だった。

社内の管理画面でも、更新直後に古い値が残り続ける不具合が繰り返し報告されたことがある。原因を洗い直すとデータキャッシュ側で再検証のタグ付けが漏れていただけで、no-storeで全部止める代わりに該当データだけrevalidateTagで再検証する形に直すと、他のキャッシュは効かせたまま最新化できた。

DevBookPath のマップで確認する

この本の学習パス上の位置づけ・前後の読書順は、DevBookPath のグラフで辿れます。

👉 フロントエンドの地図を見る

📖 Amazon で購入する


本記事のリンクには Amazon アソシエイト等の広告が含まれる場合があります。リンク経由の購入で運営者に紹介料が支払われることがあります。

この記事を共有

この地図を共有