Использование use cache
Директива use cache
позволяет пометить маршрут, React-компонент или функцию как кэшируемые. Она может использоваться в начале файла, чтобы указать, что все экспорты в файле должны кэшироваться, или внутри функции или компонента для кэширования возвращаемого значения.
Использование
use cache
в настоящее время является экспериментальной функцией. Чтобы включить её, добавьте опцию useCache
в ваш файл next.config.ts
:
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
useCache: true,
},
}
export default nextConfig
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
useCache: true,
},
}
module.exports = nextConfig
Полезно знать:
use cache
также можно включить с помощью опцииdynamicIO
.
Затем добавьте use cache
на уровне файла, компонента или функции:
// На уровне файла
'use cache'
export default async function Page() {
// ...
}
// На уровне компонента
export async function MyComponent() {
'use cache'
return <></>
}
// На уровне функции
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
Как работает use cache
Ключи кэша
Ключ записи кэша генерируется с использованием сериализованной версии её входных данных, которые включают:
- ID сборки (генерируется для каждой сборки)
- ID функции (уникальный идентификатор функции)
- Сериализуемые аргументы функции (или пропсы).
Аргументы, переданные в кэшированную функцию, а также любые значения, которые она читает из родительской области видимости, автоматически становятся частью ключа. Это означает, что одна и та же запись кэша будет повторно использоваться, пока её входные данные остаются неизменными.
Несериализуемые аргументы
Любые несериализуемые аргументы, пропсы или замкнутые значения превращаются в ссылки внутри кэшированной функции и могут быть только переданы, но не проверены или изменены. Эти несериализуемые значения будут заполнены во время запроса и не станут частью ключа кэша.
Например, кэшированная функция может принимать JSX как пропс children
и возвращать <div>{children}</div>
, но не сможет анализировать сам объект children
. Это позволяет вкладывать некэшированный контент внутрь кэшированного компонента.
function CachedComponent({ children }: { children: ReactNode }) {
'use cache'
return <div>{children}</div>
}
function CachedComponent({ children }) {
'use cache'
return <div>{children}</div>
}
Возвращаемые значения
Возвращаемое значение кэшируемой функции должно быть сериализуемым. Это гарантирует, что кэшированные данные могут быть правильно сохранены и извлечены.
use cache
во время сборки
При использовании в начале layout или page, сегмент маршрута будет предварительно отрендерен, что позволит впоследствии перевалидировать его.
Это означает, что use cache
нельзя использовать с API времени запроса, такими как cookies
или headers
.
use cache
во время выполнения
На сервере записи кэша отдельных компонентов или функций будут кэшироваться в памяти.
Затем на клиенте любой контент, возвращаемый из серверного кэша, будет храниться в памяти браузера в течение сессии или до перевалидации.
Во время перевалидации
По умолчанию use cache
имеет период перевалидации на стороне сервера в 15 минут. Хотя этот период может быть полезен для контента, не требующего частых обновлений, вы можете использовать API cacheLife
и cacheTag
для настройки времени перевалидации отдельных записей кэша.
cacheLife
: Настройка времени жизни записи кэша.cacheTag
: Создание тегов для перевалидации по требованию.
Оба этих API интегрируются между уровнями кэширования клиента и сервера, что означает, что вы можете настроить семантику кэширования в одном месте, и она будет применяться везде.
Подробнее см. в документации API cacheLife
и cacheTag
.
Примеры
Кэширование всего маршрута с use cache
Для предварительного рендеринга всего маршрута добавьте use cache
в начало обоих файлов layout
и page
. Каждый из этих сегментов рассматривается как отдельная точка входа в ваше приложение и будет кэшироваться независимо.
'use cache'
export default function Layout({ children }: { children: ReactNode }) {
return <div>{children}</div>
}
'use cache'
export default function Layout({ children }) {
return <div>{children}</div>
}
Любые компоненты, импортированные и вложенные в файл page
, унаследуют поведение кэширования page
.
'use cache'
async function Users() {
const users = await fetch('/api/users')
// перебор пользователей
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
'use cache'
async function Users() {
const users = await fetch('/api/users')
// перебор пользователей
}
export default function Page() {
return (
<main>
<Users />
</main>
)
}
Полезно знать:
- Если
use cache
добавлен только вlayout
илиpage
, кэшироваться будет только этот сегмент маршрута и любые компоненты, импортированные в него.- Если какие-либо вложенные дочерние элементы маршрута используют Dynamic API, то маршрут откажется от предварительного рендеринга.
Кэширование вывода компонента с use cache
Вы можете использовать use cache
на уровне компонента для кэширования любых запросов или вычислений, выполняемых внутри этого компонента. Запись кэша будет повторно использоваться, пока сериализованные пропсы дают одинаковое значение в каждом экземпляре.
export async function Bookings({ type = 'haircut' }: BookingsProps) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
interface BookingsProps {
type: string
}
export async function Bookings({ type = 'haircut' }) {
'use cache'
async function getBookingsData() {
const data = await fetch(`/api/bookings?type=${encodeURIComponent(type)}`)
return data
}
return //...
}
Кэширование вывода функции с use cache
Поскольку вы можете добавить use cache
к любой асинхронной функции, вы не ограничены кэшированием только компонентов или маршрутов. Вы можете кэшировать сетевой запрос, запрос к базе данных или медленное вычисление.
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
export async function getData() {
'use cache'
const data = await fetch('/api/data')
return data
}
Переплетение
Если вам нужно передать несериализуемые аргументы в кэшируемую функцию, вы можете передать их как children
. Это означает, что ссылка children
может изменяться без влияния на запись кэша.
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }: { children: ReactNode }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
export default async function Page() {
const uncachedData = await getData()
return (
<CacheComponent>
<DynamicComponent data={uncachedData} />
</CacheComponent>
)
}
async function CacheComponent({ children }) {
'use cache'
const cachedData = await fetch('/api/cached-data')
return (
<div>
<PrerenderedComponent data={cachedData} />
{children}
</div>
)
}
Вы также можете передавать Server Actions через кэшированные компоненты в Client Components без их вызова внутри кэшируемой функции.
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Выполнение серверного обновления
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({
performUpdate,
}: {
performUpdate: () => Promise<void>
}) {
'use cache'
// Не вызывайте performUpdate здесь
return <ClientComponent action={performUpdate} />
}
import ClientComponent from './ClientComponent'
export default async function Page() {
const performUpdate = async () => {
'use server'
// Выполнение серверного обновления
await db.update(...)
}
return <CacheComponent performUpdate={performUpdate} />
}
async function CachedComponent({ performUpdate }) {
'use cache'
// Не вызывайте performUpdate здесь
return <ClientComponent action={performUpdate} />
}
'use client'
export default function ClientComponent({
action,
}: {
action: () => Promise<void>
}) {
return <button onClick={action}>Update</button>
}
'use client'
export default function ClientComponent({ action }) {
return <button onClick={action}>Update</button>
}
Поддержка платформ
Вариант развертывания | Поддерживается |
---|---|
Сервер Node.js | Да |
Docker-контейнер | Да |
Статический экспорт | Нет |
Адаптеры | Зависит от платформы |
Узнайте, как настроить кэширование при самостоятельном хостинге Next.js.
История версий
Версия | Изменения |
---|---|
v15.0.0 | "use cache" представлен как экспериментальная функция. |