GitHub Skill

nextjs-caching-architecture

The 4 layers of caching (Memoization, Data Cache, Full Route, Router Cache).

HoangNguyen0403☆ 143 仓库 Stars48 仓库 Forks

安装与使用

请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。

查看来源 ↗使用指南

技能说明

Caching Architecture

Priority: P1 (HIGH)

Next.js has 4 distinct caching layers. Understanding them prevents stale data bugs.

The 4 Layers

Layer Where Duration Purpose Control
1. Request Memoization Server Per Request Deduplicate same fetch() calls in one render pass. AbortController
2. Data Cache Server Persistent Store data across user requests. revalidateTag
3. Full Route Cache Server Persistent Store HTML/RSC payload. (Static Rendering). revalidatePath
4. Router Cache Client Session (< 5m) Navigating back/forward without server hit. router.refresh()

1. Request Memoization

  • Behavior: Calling getUser(1) in layout, page, and component only triggers 1 network call.

  • Key: Matches URL and Options exactly.

  • Non-Fetch: For DB calls/Prisma, use React cache() manually.

    import { cache } from 'react';
    const getItem = cache(async (id) => db.item.findUnique({ id }));
    

2. Data Cache (The "Server Persistence")

  • Default: fetch tracks cache indefinitely (force-cache).

  • Scaling:

    • Vercel: Shared globally via KV/Blob.
    • Self-Hosted: Stored in filesystem (Pod ephemeral storage). Critical: Must configure a shared cacheHandler (Redis) for multi-pod Kubernetes setups, otherwise pods have desynchronized caches.
  • Granular Control: Use unstable_cache for DB queries caching.

    import { unstable_cache } from 'next/cache';
    const getCachedUser = unstable_cache(
      async (id) => db.user.find(id),
      ['users-key'],
      { tags: ['users'], revalidate: 60 },
    );
    

3. Router Cache (The "Client Stale")

  • Problem: User updates a listing, navigates back, and sees old data.
  • Cause: Client-side Router Cache holds payload for 30s (dynamic) or 5m (static).
  • Fix: Call router.refresh() in a Client Component or revalidatePath() in a Server Action (which automatically invalidates Router Cache).

Strategies

  • Opt-Out (Real-Time):
    • Data: fetch(..., { cache: 'no-store' })
    • Route: export const dynamic = 'force-dynamic'
  • On-Demand (CMS/Admin):
    • Use revalidateTag('collection') for surgical updates. Better than revalidatePath (which nukes the whole URL).

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!