返回笔记列表
01 · NOTES / WebGIS 开发

第 26 节 · 缓存体系全解

2026 年 9 月 1 日

第 26 节 · 缓存体系全解

📌 版本信息:Next.js 15.x(⚠️ Next 14→15 缓存默认值大改:fetch 默认不再缓存,本节以 15 为准;2026-08-29 核对) 📚 来源:Next.js · CachingrevalidateTag ⚠️ 这一部分是 Next 社区公认"最绕"的知识——本节只讲你用得上的三层,其余认脸。

一、这一节的目标

  1. 分清 Next 缓存的三层:请求记忆 / 数据缓存 / 路由缓存
  2. 掌握数据缓存的两个开关:revalidate(时间)与 revalidateTag(按需)
  3. 理解"写完数据要使缓存失效"——CRUD 应用的关键一步
  4. 认识 Client Router Cache 与最常见的"为什么页面没更新"

二、三层缓存地图

缓存什么 作用范围 控制
① 请求记忆(Request Memoization) 同一次渲染内的重复 fetch 单次渲染过程 自动(无需配置)
② 数据缓存(Data Cache) fetch 的结果跨请求复用 服务端持久 cache / next.revalidate / tags
③ 路由缓存(Router Cache) 已访问页面的 RSC 载荷 浏览器内存(导航体验) router.refresh() / 过期时间
(认脸)Full Route Cache 整页 HTML+RSC 服务端 revalidate/动态API 改变判定

①的价值:一个页面里三个组件都 fetch 同一个接口——真实网络只发一次(去重)。零成本白拿


三、数据缓存:时间失效(revalidate)

// 内容更新慢的数据:缓存 5 分钟
fetch('https://api.example.com/stats', { next: { revalidate: 300 } });
// 300 秒内的访问直接用缓存;第 301 秒的第一个请求触发后台再生(ISR 语义),先返回旧值——"stale-while-revalidate"

四、按需失效:revalidateTag(CRUD 应用的关键)

场景:文章详情页缓存了 5 分钟——用户在后台改了文章,前台要多久看到?答案:最多 5 分钟。要"改完立即可见",用标签失效

// ① 取数时打标签:
fetch(`https://api.example.com/posts/${slug}`, {
  next: { tags: ['posts', `post-${slug}`] },   // 可打多个标签
});

// ② 数据变更处(Route Handler 的 POST/PUT/DELETE 里)按需失效:
import { revalidateTag } from 'next/cache';
export async function PUT(request, { params }) {
  await updatePost(params.slug, await request.json());
  revalidateTag(`post-${params.slug}`);   // 精准失效这一篇
  revalidateTag('posts');                 // 列表页也失效
  return NextResponse.json({ ok: true });
}
// 兄弟 API:revalidatePath('/blog')——按路径整页失效(粗粒度)

记住这个模式写操作 + revalidateTag = 缓存型应用的"立即可见"。C-03c 博客的后台保存逻辑里就必须有它(否则你会以为"改了没生效"是 bug——其实是缓存,Next 最著名的困惑)。


五、Router Cache 与"页面没更新"三查

浏览器端还会缓存已访问页面的 RSC 载荷(前进/后退瞬时)。它带来的经典困惑与三查:

"我改了数据,页面怎么还是旧的?"
 ├─ ① 数据缓存没失效?→ 该加 revalidateTag/revalidatePath
 ├─ ② 客户端进的是缓存的 RSC?→ 在变更后调 router.refresh() 或用 revalidatePath
 └─ ③ build 产物没更新?→ 重新 build/部署(静态页是构建时固化的)

六、自测题

  1. 请求记忆解决什么?需要配置吗?
  2. revalidate: 300 的完整语义(包括第 301 秒的行为)?
  3. 标签失效的模式两步是什么?为什么比"全站 no-store"好?
  4. "后台改了文章前台没变"的三查顺序?
  5. cache: 'no-store' 用在哪类数据上?

参考答案

  1. 单次渲染内重复 fetch 去重;自动、免费。
  2. 5 分钟内用缓存;到期后第一个请求触发后台再生并先返回旧值(stale-while-revalidate)。
  3. 取数打 tags + 写操作处 revalidateTag;比全站不缓存保住了"绝大多数读取走缓存"的性能,只在写入时精准失效。
  4. 先查数据缓存失效、再查客户端 Router Cache(refresh)、最后查部署产物。
  5. 实时性要求高的数据(股价/在线状态/实时位置——GIS 实时大屏的轮询接口)。

七、下一步

缓存不再玄学 → 第 27 节:与地图集成模式,模块 03 收官——Next 里安全地跑地图。

TAGSweb