Route Handler · 三层缓存边界

缓存决策实验台

把“整个响应能否公开复用”“处理器是否要在请求时执行”“某个数据函数能否单独缓存”分开判断,避免把三个问题压成一句“GET 会缓存”。

GET ≠ 自动缓存
用户专属 ≠ 公共共享
① 运行模式与方法
② 请求时依赖与数据来源
请求时

当前结论:GET 仍不会自动进入整响应缓存

本项目关闭 Cache Components;没有显式 force-static 时,Route Handler 默认按请求执行。

LAYER A · 整个响应

是否可预渲染并公开共享?

✕ 默认不共享

GET 只是必要条件之一,不是自动缓存开关。

LAYER B · 处理器执行

是否必须在请求时执行?

✓ 必须执行

默认动态 Route Handler 会在真实请求到达时运行。

LAYER C · 数据函数

是否可独立缓存数据读取?

— 未启用

勾选独立 helper 后再判断;不要把 'use cache' 直接写进 GET 主体。

判定轨迹

每一步都显示文字状态,不只依赖颜色。

  1. 方法门槛

    ✓ 进入 GET 判定

    只有 GET 继续讨论整响应预渲染;HEAD、POST、PATCH 等不进入这一层。

  2. 依赖扫描

    ✓ 无请求依赖

    当前没有勾选请求时依赖或用户专属数据。

  3. 整响应策略

    ! 默认动态

    Cache Components 关闭且未声明 force-static。

  4. 数据函数策略

    — 未启用 helper

    整响应与内部数据读取要分开判断。

为什么得到这个结论

由强到弱列出
  • 项目当前关闭 Cache Components,Route Handlers 默认不缓存。
  • GET 本身不等于缓存;完全公开、确定性且无请求依赖仍只是具备候选条件。

风险警告

先守住数据边界
  • 不要根据“方法是 GET”就推断响应已经缓存。

对应的代码形态

示意边界,不替代压测
// next.config.ts
const nextConfig = {
  cacheComponents: false,
}

// app/api/catalog/route.ts
export async function GET() {
  // 默认按请求执行;GET 并不自动等于缓存
  return Response.json({ scope: 'public' })
}

一键挑战

用反例检查自己是否混淆了三层缓存。