Skip to content

缓存和重新验证

¥Caching and Revalidating

缓存是一种存储数据获取和其他计算结果的技术,以便将来对相同数据的请求能够更快地得到处理,而无需重复工作。重新验证允许你更新缓存条目,而无需重建整个应用。

¥Caching is a technique for storing the result of data fetching and other computations so that future requests for the same data can be served faster, without doing the work again. While revalidation allows you to update cache entries without having to rebuild your entire application.

Next.js 提供了一些 API 来处理缓存和重新验证。本指南将引导你了解何时以及如何使用它们。

¥Next.js provides a few APIs to handle caching and revalidation. This guide will walk you through when and how to use them.

fetch

默认情况下,fetch 请求不会被缓存。你可以通过将 cache 选项设置为 'force-cache' 来缓存单个请求。

¥By default, fetch requests are not cached. You can cache individual requests by setting the cache option to 'force-cache'.

tsx
export default async function Page() {
  const data = await fetch('https://...', { cache: 'force-cache' })
}

需要了解:虽然默认情况下不缓存 fetch 请求,但 Next.js 会对包含 fetch 请求的路由进行 prerender 处理,并缓存 HTML。如果你想保证路由是 dynamic,请使用 connection API

¥Good to know: Although fetch requests are not cached by default, Next.js will prerender routes that have fetch requests and cache the HTML. If you want to guarantee a route is dynamic, use the connection API.

为重新验证 fetch 请求返回的数据,你可以使用 next.revalidate 选项。

¥To revalidate the data returned by a fetch request, you can use the next.revalidate option.

tsx
export default async function Page() {
  const data = await fetch('https://...', { next: { revalidate: 3600 } })
}

这将在指定的秒数后重新验证数据。

¥This will revalidate the data after a specified amount of seconds.

有关更多信息,请参阅 fetch API 参考

¥See the fetch API reference to learn more.

unstable_cache

unstable_cache 允许你缓存数据库查询和其他异步函数的结果。要使用它,请将 unstable_cache 封装在该函数周围。例如:

¥unstable_cache allows you to cache the result of database queries and other async functions. To use it, wrap unstable_cache around the function. For example:

tsx
import { db } from '@/lib/db'
export async function getUserById(id: string) {
  return db
    .select()
    .from(users)
    .where(eq(users.id, id))
    .then((res) => res[0])
}
tsx
import { unstable_cache } from 'next/cache'
import { getUserById } from '@/app/lib/data'

export default async function Page({
  params,
}: {
  params: Promise<{ userId: string }>
}) {
  const { userId } = await params

  const getCachedUser = unstable_cache(
    async () => {
      return getUserById(userId)
    },
    [userId] // add the user ID to the cache key
  )
}

该函数接受第三个可选对象来定义如何重新验证缓存。它接受:

¥The function accepts a third optional object to define how the cache should be revalidated. It accepts:

  • tags:Next.js 用于重新验证缓存的标签数组。

    ¥tags: an array of tags used by Next.js to revalidate the cache.

  • revalidate:缓存重新验证后的秒数。

    ¥revalidate: the number of seconds after cache should be revalidated.

tsx
const getCachedUser = unstable_cache(
  async () => {
    return getUserById(userId)
  },
  [userId],
  {
    tags: ['user'],
    revalidate: 3600,
  }
)

有关更多信息,请参阅 unstable_cache API 参考

¥See the unstable_cache API reference to learn more.

revalidateTag

revalidateTag 用于根据标签和事件重新验证缓存条目。要将其与 fetch 一起使用,请首先使用 next.tags 选项标记该函数:

¥revalidateTag is used to revalidate a cache entries based on a tag and following an event. To use it with fetch, start by tagging the function with the next.tags option:

tsx
export async function getUserById(id: string) {
  const data = await fetch(`https://...`, {
    next: {
      tags: ['user'],
    },
  })
}

或者,你可以使用 tags 选项标记 unstable_cache 函数:

¥Alternatively, you can mark an unstable_cache function with the tags option:

tsx
export const getUserById = unstable_cache(
  async (id: string) => {
    return db.query.users.findFirst({ where: eq(users.id, id) })
  },
  ['user'], // Needed if variables are not passed as parameters
  {
    tags: ['user'],
  }
)

然后,在 路由处理程序 或服务器操作中调用 revalidateTag

¥Then, call revalidateTag in a Route Handler or Server Action:

tsx
import { revalidateTag } from 'next/cache'

export async function updateUser(id: string) {
  // Mutate data
  revalidateTag('user')
}

你可以在多个函数中重复使用同一个标签,以便一次性重新验证所有函数。

¥You can reuse the same tag in multiple functions to revalidate them all at once.

有关更多信息,请参阅 revalidateTag API 参考

¥See the revalidateTag API reference to learn more.

revalidatePath

revalidatePath 用于重新验证路由和事件。要使用它,请在 路由处理程序 或服务器操作中调用它:

¥revalidatePath is used to revalidate a route and following an event. To use it, call it in a Route Handler or Server Action:

tsx
import { revalidatePath } from 'next/cache'

export async function updateUser(id: string) {
  // Mutate data
  revalidatePath('/profile')

有关更多信息,请参阅 revalidatePath API 参考

¥See the revalidatePath API reference to learn more.