← 返回缓存测试

Next.js 缓存机制完整对比

📊 四种缓存机制概览

Next.js 使用四种不同的缓存机制来优化性能,每种缓存都有不同的作用范围和生命周期。

🔄

Request Memoization

单次渲染

📦

Data Cache

跨请求持久化

🗺️

Full Route Cache

构建时+运行时

🧭

Router Cache

客户端会话

📋 详细对比表

特性Request MemoizationData CacheFull Route CacheRouter Cache
存储位置服务端内存服务端文件系统服务端文件系统客户端内存
生命周期单次渲染周期持久化(直到重新验证)持久化(直到重新构建)30秒或用户会话
作用范围同一渲染中的重复请求所有 fetch 请求整个路由/页面客户端导航的路由
何时生效自动(React 内置)默认所有 fetch静态路由(自动)客户端导航(自动)
如何禁用❌ 无法禁用cache: 'no-store'dynamic = 'force-dynamic'router.refresh()
刷新页面重置(新渲染周期)保持(使用缓存)保持(使用缓存)清空
重启服务器N/A保持(持久化)保持(持久化)N/A(客户端)
性能优势减少重复请求减少 API 调用减少服务端渲染加快客户端导航

🏗️ 缓存层级结构

1

Router Cache(客户端)

客户端导航时首先检查

2

Full Route Cache(服务端)

如果未命中客户端缓存,检查服务端预渲染的路由

3

Data Cache(服务端)

如果需要渲染,检查 fetch 请求的缓存

4

Request Memoization(服务端)

同一渲染周期内去重重复请求

💡 使用场景和最佳实践

🔄 Request Memoization

✅ 适用场景:

  • 多个组件需要同一份数据
  • 父子组件共享数据
  • 并行渲染的组件

💡 最佳实践:

  • 不需要手动传递数据
  • 每个组件独立请求
  • 自动去重,无需担心

📦 Data Cache

✅ 适用场景:

  • 静态内容(博客、文档)
  • 定期更新的内容
  • 第三方 API 数据

💡 最佳实践:

  • 使用 revalidate 定期更新
  • 实时数据用 no-store
  • 用户相关数据禁用缓存

🗺️ Full Route Cache

✅ 适用场景:

  • 静态页面(营销页面)
  • 博客文章、文档
  • 产品列表页

💡 最佳实践:

  • 尽量让页面变成静态的
  • 避免不必要的 dynamic functions
  • 使用 ISR 定期更新

🧭 Router Cache

✅ 适用场景:

  • 频繁前后导航的页面
  • 多页面应用
  • 需要快速返回的场景

💡 最佳实践:

  • 使用 Link 组件自动预取
  • 需要时用 router.refresh()
  • 理解 30 秒缓存时长

❓ 常见问题

Q1: 为什么我的页面没有被缓存?

检查是否使用了 dynamic functions(cookies(), headers(), searchParams)或 cache: 'no-store'。这些会让页面变成动态渲染。

Q2: 如何查看哪些路由是静态的?

运行 pnpm build 查看输出:

○ /static-page ← 静态

λ /dynamic-page ← 动态

Q3: 如何清除所有缓存?

开发环境:删除 .next 目录并重启

生产环境:重新构建和部署

客户端:刷新浏览器或 router.refresh()

Q4: 开发环境和生产环境的缓存行为一样吗?

不完全一样。Full Route Cache 只在生产环境完全生效。 开发环境为了更好的开发体验,某些缓存行为会被修改。

🔧 调试技巧

1. 查看构建输出

pnpm build

查看哪些路由是静态的(○)、哪些是动态的(λ)

2. 查看 .next 目录

ls -la .next/server/app/

静态页面会有 .html 文件,动态页面只有 .js

3. 使用时间戳

在页面上显示渲染时间,刷新页面观察时间是否变化

4. 查看日志

在服务端代码中添加 console.log,查看执行次数

5. 网络面板

打开浏览器开发者工具,查看网络请求的数量和时间

6. React DevTools

查看组件的重新渲染情况