基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

如何在 App Router 中通过 fetch 配置缓存策略(如 force-cache, no-store)来实现 SSG 或 SSR?

知识点图片

在 Next.js App Router 中,Next.js 扩展了原生的 Web fetch API。你可以通过在 fetch 函数的第二个参数中设置 cachenext 选项,来精确控制数据的缓存行为,从而实现 SSG(静态站点生成)、SSR(服务端渲染)或 ISR(增量静态再生)。

以下是具体的配置方法:

1. 实现 SSG (Static Site Generation) - 默认行为

SSG 意味着数据在 构建时 (Build Time) 获取,生成的 HTML 被缓存并在用户访问时复用。

  • 配置策略: force-cache (默认)
  • 适用场景: 博客文章、文档、营销页面等内容不经常变动的数据。
tsx
// app/page.tsx

async function getData() {
  // 'force-cache' 是默认值,通常可以省略
  // 这告诉 Next.js:在构建时获取数据并无限期缓存
  const res = await fetch('https://api.example.com/data', { 
    cache: 'force-cache' 
  });

  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();
  return <main>{/* 使用 data 渲染 */}</main>;
}

2. 实现 SSR (Server-Side Rendering)

SSR 意味着数据在 每次请求时 (Request Time) 重新获取,HTML 是在服务器上为每个用户实时生成的。

  • 配置策略: no-store
  • 适用场景: 实时股票数据、用户个性化仪表盘、经常变化的数据。
tsx
// app/page.tsx

async function getData() {
  // 'no-store' 告诉 Next.js:不要缓存这个请求
  // 每次用户刷新页面,都会重新向 API 发起请求
  const res = await fetch('https://api.example.com/data', { 
    cache: 'no-store' 
  });

  return res.json();
}

export default async function Page() {
  const data = await getData();
  return <main>{/* 渲染实时数据 */}</main>;
}

3. 实现 ISR (Incremental Static Regeneration)

ISR 是 SSG 和 SSR 的混合体。页面在构建时生成,但在经过指定的时间(秒)后,如果有新请求进入,Next.js 会在后台重新验证并更新缓存。

  • 配置策略: next: { revalidate: <seconds> }
  • 适用场景: 电商产品列表(价格偶尔变动)、新闻列表。
tsx
// app/page.tsx

async function getData() {
  // 设置 revalidate 为 60 秒
  // 意味着数据会被缓存 60 秒。60秒后的第一个请求会触发后台更新。
  const res = await fetch('https://api.example.com/data', { 
    next: { revalidate: 60 } 
  });

  return res.json();
}

export default async function Page() {
  const data = await getData();
  return <main>{/* 渲染数据 */}</main>;
}

总结对比表

渲染模式 fetch 配置 行为描述 适用场景
SSG (静态) { cache: 'force-cache' }
(或省略)
构建时获取,永久缓存。 博客、关于我们、帮助中心
SSR (动态) { cache: 'no-store' } 每次请求时获取,不缓存。 实时数据、个性化内容
ISR (增量) { next: { revalidate: N } } 缓存 N 秒,过期后后台更新。 产品详情、新闻流

补充:如果不使用 fetch (如直接查数据库)

如果你不使用 fetch (例如直接使用 Prisma 或 Mongoose 连接数据库),你无法使用上述参数。此时,你需要使用 Route Segment Config (路由段配置) 来控制页面的渲染策略。

layout.tsxpage.tsx 文件顶部导出以下变量:

强制 SSR (相当于 no-store):

tsx
export const dynamic = 'force-dynamic';

设置 ISR (相当于 revalidate):

tsx
export const revalidate = 60; // 每60秒重新验证

强制 SSG (默认):

tsx
export const dynamic = 'force-static';
00:00
00:00