How to implement Incremental Static Regeneration (ISR)
Details
增量静态再生成(ISR)使您能够:
- 在不重建整个站点的情况下更新静态内容
- 通过为大多数请求提供预渲染的静态页面来减少服务器负载
- 确保自动为页面添加适当的
cache-control
头部 - 处理大量内容页面而无需长时间的
next build
时间
以下是一个最小示例:
- TypeScript
- JavaScript
pages/blog/[id].tsx
import type { GetStaticPaths, GetStaticProps } from 'next'
interface Post {
id: string
title: string
content: string
}
interface Props {
post: Post
}
export const getStaticPaths: GetStaticPaths = async () => {
const posts = await fetch('https://api.vercel.app/blog').then((res) =>
res.json()
)
const paths = posts.map((post: Post) => ({
params: { id: String(post.id) },
}))
// 我们将在构建时仅预渲染这些路径。
// { fallback: 'blocking' } 将在路径不存在时
// 按需服务端渲染页面。
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps<Props> = async ({
params,
}: {
params: { id: string }
}) => {
const post = await fetch(`https://api.vercel.app/blog/${params.id}`).then(
(res) => res.json()
)
return {
props: { post },
// Next.js 将在请求到达时使缓存失效,
// 最多每 60 秒一次。
revalidate: 60,
}
}
export default function Page({ post }: Props) {
return (
<main>
<h1>{post.title}</h1>
<p>{post.content}</p>
</main>
)
}
pages/blog/[id].jsx
export async function getStaticPaths() {
const posts = await fetch('https://api.vercel.app/blog').then((res) =>
res.json()
)
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// 我们将在构建时仅预渲染这些路径。
// { fallback: false } 表示其他路由应该返回 404。
return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
const post = await fetch(`https://api.vercel.app/blog/${params.id}`).then(
(res) => res.json()
)
return {
props: { post },
// Next.js 将在请求到达时使缓存失效,
// 最多每 60 秒一次。
revalidate: 60,
}
}
export default function Page({ post }) {
return (
<main>
<h1>{post.title}</h1>
<p>{post.content}</p>
</main>
)
}
这个示例的工作原理如下:
- 在
next build
期间,所有已知的博客文章都会被生成(此示例中有 25 篇) - 对这些页面的所有请求(例如
/blog/1
)都会被缓存并立即响应 - 60 秒后,下一个请求仍会显示缓存的(过期的)页面
- 缓存失效,新版本的页面开始在后台生成