BluePeriod Docs
開発トラブルシューティング

Next.js Caching and Rendering Troubleshooting

Next.jsのキャッシュとレンダリングに関する問題と解決策

Next.js Caching and Rendering Troubleshooting

このドキュメントは、Next.jsのキャッシュとレンダリングに関する一般的な問題と解決策を記録します。

問題1: 検索パラメータが変更されてもページが更新されない

症状

  • URLの検索パラメータ(query string)を変更しても、ページの内容が更新されない
  • サーバーサイドのログでは正しいパラメータが渡されているが、UIに反映されない
  • ページをリロードすると正しい内容が表示される

根本原因

Next.js 13以降のApp Routerでは、サーバーコンポーネントはデフォルトでキャッシュされます。これにより、同じルートへのナビゲーション時に、以前のレンダリング結果が再利用される場合があります。

解決策

方法1: 動的レンダリングを強制する(推奨)

ページコンポーネントにdynamic設定を追加します。

// ✅ 解決策
export const dynamic = 'force-dynamic';

export default async function MyPage({ searchParams }) {
    const params = await searchParams;
    const query = params.q;
    
    // クエリパラメータに基づいてデータを取得
    const data = await fetchData(query);
    
    return <div>{/* ... */}</div>;
}

方法2: revalidateを設定する

特定の時間ごとにキャッシュを無効化します。

// ✅ 代替案(定期的な更新で十分な場合)
export const revalidate = 0; // 常に再検証

export default async function MyPage({ searchParams }) {
    // ...
}

方法3: キャッシュタグを使用する

より細かい制御が必要な場合は、キャッシュタグを使用します。

import { unstable_cache } from 'next/cache';

const getCachedData = unstable_cache(
    async (query) => fetchData(query),
    ['data-cache'],
    { revalidate: 60 }
);

実際の事例: Libraryページの検索機能

状況:

  • Libraryページで検索バーに文字を入力しても、結果が更新されない
  • サーバーログでは正しくフィルタリングされている
  • ページをリロードすると正しい結果が表示される

原因:

// ❌ 問題のあるコード
export default async function LibraryPage({ searchParams }) {
    const params = await searchParams;
    const query = params.q;
    
    // データを取得してフィルタリング
    const items = await fetchAndFilterItems(query);
    
    return <LibraryPageClient initialItems={items} />;
}
// ↑ デフォルトでキャッシュされるため、queryが変わっても再レンダリングされない

解決:

// ✅ 解決策
export const dynamic = 'force-dynamic'; // 追加

export default async function LibraryPage({ searchParams }) {
    const params = await searchParams;
    const query = params.q;
    
    const items = await fetchAndFilterItems(query);
    
    return <LibraryPageClient initialItems={items} />;
}

dynamic設定の種類

設定値説明使用場面
'auto' (デフォルト)Next.jsが自動的に判断通常のページ
'force-dynamic'常に動的レンダリング検索、フィルタリング、ユーザー固有のデータ
'force-static'常に静的生成変更されないコンテンツ
'error'静的生成を強制し、動的関数使用時にエラー静的生成を保証したい場合

ベストプラクティス

  1. 必要な場合のみ動的レンダリングを使用する

    • パフォーマンスのため、可能な限り静的生成を活用
    • 検索、フィルタリング、ユーザー固有のデータなど、動的な内容が必要な場合のみforce-dynamicを使用
  2. キャッシュの粒度を適切に設定する

    • ページ全体ではなく、特定のデータフェッチのみをキャッシュすることも検討
    • fetch関数のcacheオプションやnext.revalidateを活用
  3. デバッグ方法

    • サーバーログでレンダリングのタイミングを確認
    • Next.jsの開発モードでは、キャッシュが無効化されることに注意
    • 本番環境での動作を確認する
  4. 関連する設定

    // ページレベルの設定
    export const dynamic = 'force-dynamic';
    export const revalidate = 60; // 60秒ごとに再検証
    export const fetchCache = 'force-no-store'; // fetchのキャッシュを無効化

関連する問題

クライアントコンポーネントでの検索パラメータ

クライアントコンポーネントでuseSearchParamsを使用する場合は、自動的に動的レンダリングになります。

'use client';

import { useSearchParams } from 'next/navigation';

export default function ClientComponent() {
    const searchParams = useSearchParams();
    const query = searchParams.get('q');
    
    // 自動的に動的レンダリング
}

参考リンク


最終更新: 2025-11-27
関連タスク: feat-explore-phase7d (Explore/Library/MyWorksページのUI統一)

On this page