KAKUTA TECH BLOG

Blog Article

Next.js におけるキャッシュについて

はじめに

Next.js でブログサイトや Web アプリケーションを作り始めると、「キャッシュ」という言葉を頻繁に目にするようになります。しかし、キャッシュは仕組みが見えにくく、初学者にとってはとても分かりづらい概念です。

「キャッシュとは何なのか」「キャッシュすると何が起きるのか」「なぜ使う必要があるのか」、そして「逆にキャッシュを使わないほうが良い場面はいつなのか」。これらを理解しないまま設定してしまうと、ページが更新されなかったり、想定外の古いデータが表示されたりといった問題に直面します。

この記事では、Next.js におけるキャッシュの考え方を解説します。最後には、どんな場面でキャッシュを使い、どんな場面で使わないのかを整理します。

参考リンク

この記事は、以下の公式ドキュメントを参考にしつつ、プログラミング初学者でも理解できるように内容を整理して執筆しています。

キャッシュとは何か

一言で言うなら、キャッシュとは一度取得した結果を保存しておき、次回以降はそれを再利用する仕組みです。

キャッシュを身近な例で考えと、

  • 毎回コンビニに行って水を買う → キャッシュなし
  • 家の冷蔵庫に水を入れておく → キャッシュあり

👉 冷蔵庫(キャッシュ)があれば、速い・楽・コストがかからない ですよね。

Web の世界では、ページの表示やデータ取得の結果を保存しておくことで、次回以降の処理を速くします。これがキャッシュです。

なぜキャッシュが必要なのか

Web アプリケーションでは、ページを表示するたびに、

  • データベースにアクセスする
  • 外部 API にリクエストを送る
  • 計算処理を行う

といった処理が発生します。これらは時間がかかり、サーバーにも負荷をかけます。

キャッシュがない場合、同じページにアクセスされるたびに、同じ処理を何度も繰り返すことになります。その結果、ページ表示が遅くなり、アクセスが増えるとサーバーが耐えられなくなります。

キャッシュは、この無駄な繰り返しを防ぐために必要です。

キャッシュすると何が起きるのか

キャッシュを使うと、Next.js は「前回と同じ結果を使ってよいかどうか」を判断し、条件が合えば保存済みの結果をそのまま返します。

その結果、次のような変化が起きます。

まず、ページの表示速度が大きく向上します。データ取得やレンダリングを省略できるため、ユーザーは待ち時間をほとんど感じません。

次に、サーバーへの負荷が下がります。同じ処理を何度も実行しなくて済むため、少ないリソースで多くのアクセスを処理できます。

一方で、キャッシュには注意点もあります。保存された結果を使うということは、「最新の情報ではない可能性がある」ということです。これを理解せずに使うと、「記事を更新したのに画面に反映されない」といった問題が発生します。

キャッシュはどこに保存されるのか

キャッシュという言葉だけを聞くと、ブラウザに保存されているものを想像する人も多いですが、Next.js のキャッシュはそれだけではありません。実際には、いくつかの場所に分かれて保存され、それぞれ役割が異なります。

まず理解しておきたいのは、Next.js のキャッシュは「Next.js 自体が備えている仕組み」と「ブラウザが備えている仕組み」の両方を利用して成り立っているという点です。つまり、キャッシュは一か所にあるのではなく、表示までの流れの中で複数の段階に存在しています。

Next.js が内部で持つキャッシュ

Next.js の App Router では、フレームワーク自身がデータ取得結果や HTML をキャッシュする仕組みを持っています。これは開発者が特別なライブラリを導入しなくても、Next.js を使っているだけで自動的に利用されます。

このキャッシュは主にサーバー側に保存されます。開発環境ではローカルの実行環境、本番環境では Vercel などのホスティングサービス上のサーバーやエッジ環境に保存されます。ブラウザではなく、Next.js が動いている場所に保存される点が重要です。

この仕組みを一言で言うなら、「同じ処理を何度も実行しないために、Next.js が結果を覚えておく仕組み」です。例えば、同じ API に対する同じリクエストが何度も発生した場合、毎回 API にアクセスするのではなく、以前取得した結果を使い回します。

これがあることで、サーバーの負荷が下がり、ページの表示速度も安定します。もしこの仕組みがなければ、アクセスのたびに API 通信が発生し、表示が遅くなったり、外部 API の制限に引っかかったりする可能性があります。

fetch と Next.js のキャッシュの関係

Next.js では、データ取得に使う fetch 関数がフレームワーク用に拡張されています。単なる JavaScript の fetch ではなく、Next.js 専用の挙動が追加されている点が特徴です。

例えば、サーバーコンポーネント内で fetch を使うと、その結果は自動的にキャッシュされます。開発者が何も指定しなければ、「このデータは再利用できる」と Next.js が判断し、次回以降のリクエストではキャッシュを返します。

コードとしては次のような形になります。

const res = await fetch('<https://example.com/api/posts>')
const data = await res.json()

この短いコードの裏側で、Next.js は「この URL へのリクエスト結果を保存しておこう」と判断しています。

そのため、同じページが再度表示されたとき、同じ fetch が実行されても、実際にはネットワーク通信が行われない場合があります。

CDN のキャッシュ

Next.js のキャッシュを理解するとき、もう一つ重要な存在があります。それが CDN です。CDN はブラウザでも Next.js 本体でもなく、その中間に位置する仕組みです。この存在を知らないと、キャッシュの全体像がつかめません。

CDN とは Content Delivery Network の略で、世界中に配置されたサーバー群のことを指します。ユーザーがページにアクセスしたとき、毎回アプリケーションのサーバーまで通信するのではなく、地理的に近い CDN サーバーからコンテンツを配信するための仕組みです。

これを一言で言うなら、「ユーザーの近くにコピーを置いて、速く届ける仕組み」です。

Next.js を Vercel などの環境にデプロイすると、静的に生成されたページやキャッシュされたレスポンスは、この CDN 上に保存されます。つまり、Next.js のキャッシュはサーバーだけで完結するのではなく、CDN を通じて世界中に配信される形になります。

CDN があることで、例えば日本のユーザーがアクセスしたときに、アメリカにあるサーバーまで通信しに行く必要がなくなります。結果として、ページの表示が速くなり、通信量も抑えられます。

もし CDN がなければ、アクセスが集中した場合にサーバーが耐えられなくなったり、海外からのアクセスで表示が極端に遅くなったりします。そのため、Next.js のキャッシュ設計は CDN の存在を前提として考えられています。

Next.js のキャッシュと CDN の関係

Next.js の App Router では、fetch によるデータ取得や、静的生成されたページの結果がキャッシュされます。これらのキャッシュは、最終的に CDN に配置され、ユーザーからのリクエストに対して最短経路で返されます。

開発者は明示的に CDN を操作している感覚はあまりありませんが、実際には Next.js の設定や fetch のオプションによって、「CDN にどれくらいの時間キャッシュされるか」が決まっています。

例えば、再検証を行わない静的ページは、長期間 CDN に保存され続けます。一方で、一定時間ごとに更新されるページは、古いキャッシュが破棄され、新しい内容が CDN に再配置されます。

この仕組みがあることで、ブログのようなサイトでは「ほとんど変わらない記事ページは高速に配信し、更新が必要な部分だけを適切なタイミングで更新する」という運用が可能になります。

ブラウザに保存されるキャッシュ

一方で、ブラウザ側にもキャッシュは存在します。これは Next.js 特有の機能ではなく、Web ブラウザがもともと備えている仕組みです。画像や CSS、JavaScript ファイルなどの静的ファイルは、ブラウザのキャッシュに保存されます。

このキャッシュは、ページを再読み込みしたときや、別のページに移動したときに効果を発揮します。すでにダウンロード済みのファイルであれば、再度通信を行わずに表示できるため、体感速度が向上します。

ただし、ブラウザキャッシュはユーザーごとに管理されます。あるユーザーのブラウザに保存されたキャッシュは、別のユーザーには共有されません。この点が、Next.js のサーバー側キャッシュとの大きな違いです。

キャッシュの保存場所を整理すると

ここまでの内容を整理すると、Next.js に関わるキャッシュは次のように分けて考えることができます。

  • サーバー側のキャッシュ:Next.js が内部で管理し、データ取得結果や HTML を保存する
  • CDN キャッシュ:CDN に保存され、ユーザーの近くから配信されるキャッシュ
  • ブラウザキャッシュ:ブラウザが管理し、画像やスクリプトなどの静的ファイルを保存する

Next.js におけるキャッシュの全体像

Next.js のキャッシュは、大きく分けて次の考え方で成り立っています。

  • ページ全体をキャッシュする
  • データ取得結果をキャッシュする

App Router では、これらがフレームワーク側で自動的に制御されるため、開発者は「キャッシュするかしないか」を明示的に選ぶだけで済むようになっています。

データ取得とキャッシュの関係

Next.js では、fetch 関数が特別な扱いを受けています。サーバーコンポーネント内で fetch を使うと、その結果はデフォルトでキャッシュ対象になります。

一言で言うなら、

Next.js の fetch は、何もしなければ自動的にキャッシュされるという特徴があります。

なぜこの仕様なのか

ブログ記事や商品一覧のように、頻繁には変わらないデータが多いためです。毎回最新データを取得するよりも、一定期間は同じ結果を使い回したほうが効率的だからです。

コード例
const res = await fetch('<https://api.example.com/posts>')
const posts = await res.json()

このコードでは、特別な設定をしていませんが、Next.js はこの取得結果をキャッシュします。次回以降、同じ条件でアクセスされた場合は、保存された結果が使われます。

キャッシュを使う場面と理由

  1. ブログ記事一覧ページ

    ブログ記事一覧は、多くの場合、内容が頻繁には変わりません。そのため、キャッシュを使うことで高速に表示でき、サーバー負荷も下げられます。

  2. 記事詳細ページ

    公開済みの記事は、基本的に内容が固定されています。このようなページはキャッシュとの相性が非常に良いです。

キャッシュを使う理由の整理

  • 表示速度を速くしたい
  • サーバー負荷を減らしたい
  • 同じ内容を何度も計算したくない

これらに当てはまる場合は、キャッシュを使う価値があります。

キャッシュを使わない場面と理由

  1. 管理画面や下書き確認ページ

    管理画面では、常に最新の状態を表示する必要があります。キャッシュされた古い情報が表示されると、編集作業に支障が出ます。

  2. ユーザーごとに内容が変わるページ

    ログインユーザーによって表示内容が変わるページでは、キャッシュを使うと他人の情報が表示される危険があります。

キャッシュを使わない理由の整理

  • 常に最新のデータが必要
  • ユーザーごとに内容が異なる
  • リアルタイム性が求められる

このような場合は、キャッシュを無効にする必要があります。

キャッシュを無効にする方法

Next.js では、fetch にオプションを指定することでキャッシュを制御できます。

await fetch('<https://api.example.com/posts>', {
  cache: 'no-store'
})

この指定をすると、毎回最新のデータを取得します。管理画面やリアルタイム性が重要なページで使用します。

キャッシュを使い分ける考え方

ここまでの内容を整理すると、次のように考えると分かりやすくなります。

ページの性質

キャッシュ

公開済みブログ記事

使う

記事一覧ページ

使う

管理画面

使わない

ユーザーごとに変わるページ

使わない

まとめ

  • キャッシュとは、一度取得した結果を再利用する仕組みです
  • キャッシュを使うと、表示が速くなり、サーバー負荷が下がります
  • 一方で、最新性が失われる可能性があります
  • Next.js では fetch が自動的にキャッシュされます
  • ページの性質に応じて、キャッシュを使うか使わないかを判断することが重要です

おわりに

Next.js のキャッシュは、最初は難しく感じるかもしれません。しかし、「速さを取るか、最新性を取るか」という視点で考えると、理解しやすくなります。

ブログサイトを運営する上では、キャッシュを正しく使うことが、快適な閲覧体験につながります。ぜひ自分のサイト構成を思い浮かべながら、どこにキャッシュを使うべきか考えてみてください。