Кэширование и ревалидация данных
Кэширование — это техника хранения результатов запросов данных и других вычислений, чтобы последующие запросы тех же данных выполнялись быстрее, без повторного выполнения работы. Ревалидация позволяет обновлять записи в кэше без необходимости пересобирать всё приложение.
Next.js предоставляет несколько API для работы с кэшированием и ревалидацией. Это руководство покажет, когда и как их использовать.
fetch
По умолчанию запросы fetch
не кэшируются. Вы можете кэшировать отдельные запросы, установив параметр cache
в значение 'force-cache'
.
export default async function Page() {
const data = await fetch('https://...', { cache: 'force-cache' })
}
export default async function Page() {
const data = await fetch('https://...', { cache: 'force-cache' })
}
Полезно знать: Хотя запросы
fetch
по умолчанию не кэшируются, Next.js будет предварительно рендерить маршруты с запросамиfetch
и кэшировать HTML. Если вы хотите гарантировать, что маршрут будет динамическим, используйте APIconnection
.
Чтобы обновить данные, возвращаемые запросом fetch
, можно использовать параметр next.revalidate
.
export default async function Page() {
const data = await fetch('https://...', { next: { revalidate: 3600 } })
}
export default async function Page() {
const data = await fetch('https://...', { next: { revalidate: 3600 } })
}
Это приведёт к обновлению данных через указанное количество секунд.
Подробнее см. в справочнике API fetch
.
unstable_cache
unstable_cache
позволяет кэшировать результаты запросов к базе данных и других асинхронных функций. Чтобы использовать его, оберните unstable_cache
вокруг функции. Например:
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])
}
import { db } from '@/lib/db'
export async function getUserById(id) {
return db
.select()
.from(users)
.where(eq(users.id, id))
.then((res) => res[0])
}
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] // добавляем ID пользователя в ключ кэша
)
}
import { unstable_cache } from 'next/cache';
import { getUserById } from '@/app/lib/data';
export default async function Page({ params } }) {
const { userId } = await params
const getCachedUser = unstable_cache(
async () => {
return getUserById(userId)
},
[userId] // добавляем ID пользователя в ключ кэша
);
}
Функция принимает третий необязательный объект для определения способа обновления кэша. Он может содержать:
tags
: массив тегов, используемых Next.js для обновления кэша.revalidate
: количество секунд, через которое кэш должен быть обновлён.
const getCachedUser = unstable_cache(
async () => {
return getUserById(userId)
},
[userId],
{
tags: ['user'],
revalidate: 3600,
}
)
const getCachedUser = unstable_cache(
async () => {
return getUserById(userId)
},
[userId],
{
tags: ['user'],
revalidate: 3600,
}
)
Подробнее см. в справочнике API unstable_cache
.
revalidateTag
revalidateTag
используется для обновления записей в кэше по тегу после определённого события. Чтобы использовать его с fetch
, сначала пометьте функцию параметром next.tags
:
export async function getUserById(id: string) {
const data = await fetch(`https://...`, {
next: {
tags: ['user'],
},
})
}
export async function getUserById(id) {
const data = await fetch(`https://...`, {
next: {
tags: ['user'],
},
})
}
Либо пометьте функцию unstable_cache
параметром tags
:
export const getUserById = unstable_cache(
async (id: string) => {
return db.query.users.findFirst({ where: eq(users.id, id) })
},
['user'], // Необходимо, если переменные не передаются как параметры
{
tags: ['user'],
}
)
export const getUserById = unstable_cache(
async (id) => {
return db.query.users.findFirst({ where: eq(users.id, id) })
},
['user'], // Необходимо, если переменные не передаются как параметры
{
tags: ['user'],
}
)
Затем вызовите revalidateTag
в обработчике маршрута (Route Handler) или серверном действии (Server Action):
import { revalidateTag } from 'next/cache'
export async function updateUser(id: string) {
// Изменяем данные
revalidateTag('user')
}
import { revalidateTag } from 'next/cache'
export async function updateUser(id) {
// Изменяем данные
revalidateTag('user')
}
Один и тот же тег можно использовать в нескольких функциях, чтобы обновить их все одновременно.
Подробнее см. в справочнике API revalidateTag
.
revalidatePath
revalidatePath
используется для обновления маршрута после определённого события. Чтобы использовать его, вызовите его в обработчике маршрута (Route Handler) или серверном действии (Server Action):
import { revalidatePath } from 'next/cache'
export async function updateUser(id: string) {
// Изменяем данные
revalidatePath('/profile')
import { revalidatePath } from 'next/cache'
export async function updateUser(id) {
// Изменяем данные
revalidatePath('/profile')
Подробнее см. в справочнике API revalidatePath
.