Next.js unstable_cacheでビルド時間を改善する

3分で読めます
Next.js unstable_cacheでビルド時間を改善する のサムネイル

ビルド時間増加の問題

このブログサイトの記事数が増えてきた頃、ビルド時間が気になるようになりました。記事が10件から20件、30件と増えるにつれて、明らかにビルドが遅くなっていく感覚がありました。

原因を調べてみると、記事一覧やタグページ、カテゴリページの生成で、同じ記事ファイルを何度も読み込んでいることが分かりました。Next.jsのgenerateStaticParamsgenerateMetadataが、それぞれで独立してファイルシステムにアクセスしているためです。

unstable_cacheによるサーバーサイドキャッシュ

Next.js 14から提供されているunstable_cacheは、サーバーサイドの関数実行結果をキャッシュする機能です。名前に「unstable」と付いていますが、実際には安定して動作します。

関数実行結果をキャッシュし、同じ処理の重複実行を防ぎます。

TypeScript
import { unstable_cache } from "next/cache";

export const getPostsSummary = unstable_cache(
  getPostsSummaryInternal,
  ["blog-posts-summary"],
  {
    revalidate: 3600, // 1時間キャッシュ
    tags: ["blog-posts"],
  },
);

getPostsSummaryInternalの実行結果が1時間キャッシュされます。同じキーで何度呼び出されても、実際の処理は最初の1回だけです。

記事取得処理へのキャッシュ適用

記事データの取得を最適化

記事の基本情報を取得する関数にキャッシュを適用しました。この関数は記事一覧、RSS生成、検索インデックス生成で使用されており、複数の呼び出しをキャッシュで削減できます。

TypeScript
export const getPostsSummary = unstable_cache(
  getPostsSummaryInternal,
  ["blog-posts-summary"],
  {
    revalidate: 3600,
    tags: ["blog-posts"],
  },
);

タグ情報集計でのキャッシュ活用

タグ情報の生成処理でも、既にキャッシュされた記事データを活用できるようにしました。

TypeScript
export const getAllTags = unstable_cache(
  async (): Promise<Tag[]> => {
    const posts = await getPostsSummary(); // ここでキャッシュが効く
    return extractTags(posts);
  },
  ["all-tags"],
  { revalidate: 1800, tags: ["blog-posts"] }
);

ファイルシステムへのアクセスは初回の1回だけになり、その後の処理はメモリから高速で取得できます。ビルドログで各ページの生成速度の向上を確認できました。

キャッシュキー設計の注意点

最初、パラメータを持つ関数でキャッシュキーの設計を間違えてしまいました。

TypeScript
// ❌ これだと異なる引数でも同じ結果が返される
export const getBlogPostsByTag = unstable_cache(
  async (tagSlug: string) => { /* ... */ },
  ["posts-by-tag"], // 引数を無視している
  { revalidate: 1800 }
);

異なるタグでも同じ記事が表示される問題が発生しました。解決策は、キーに引数を含めることです。

TypeScript
// ✅ 引数をキーに含める
[`posts-by-tag-${tagSlug}`]

まとめ

unstable_cacheを適用することで、ビルド時のファイルアクセス回数を削減し、ビルドプロセスの高速化を実現できました。開発サーバーでの画面更新速度も向上しています。

ブログのような静的サイトでは同じデータを複数箇所で使用するため、unstable_cacheによるキャッシュ化は効果的です。キャッシュキーの設計で引数を適切に含めることで、正確なキャッシュ管理が可能になります。

この記事は役に立ちましたか?

この記事をシェア

X
Facebook
はてな
URLをコピー
utsusieのプロフィール画像

utsusie

UI Designer / Web Director