1. Введение
В мире веб-разработки кеширование — это отличный способ ускорить загрузку страниц и снизить нагрузку на сервер. Но иногда данные меняются слишком часто, или нам нужно всегда показывать только самую свежую информацию. Представьте себе интернет-магазин: если пользователь добавляет товар в корзину, он ожидает увидеть актуальное состояние корзины, а не её вчерашнюю версию из кеша. То же самое касается админ-панелей, систем мониторинга, чатов и других динамических приложений.
Вот тут и приходит на помощь опция cache: "no-store".
Кеширование по умолчанию в Server Components
Когда вы используете функцию fetch() в серверном компоненте Next.js, по умолчанию Next.js кеширует результат этого запроса. Это значит, что если несколько пользователей заходят на одну и ту же страницу, Next.js может использовать уже полученные данные, не делая новый запрос к серверу или базе данных. Это экономит ресурсы и ускоряет работу сайта.
Но что если нам нужно, чтобы каждый пользователь всегда получал свежие данные? Например, если мы делаем дашборд с обновляющейся статистикой, или работаем с персональными, приватными данными.
В таких случаях нужно отключить кеширование — и для этого есть специальная опция.
Опция cache: "no-store": что это и как работает
Параметр cache: "no-store" — это магическая палочка, которая говорит Next.js:
"Не сохраняй результат этого запроса, всегда делай новый запрос к источнику данных!"
await fetch(url, { cache: "no-store" })
Если вы укажете этот параметр, Next.js будет каждый раз обращаться к серверу или базе данных заново, игнорируя все предыдущие результаты.
Аналогия
Представьте, что вы приходите в кафе, и официант спрашивает: "Вам принести вчерашний суп? Он у нас остался!"
Вы отвечаете: "Нет, пожалуйста, только что приготовленный!"
Вот это и есть no-store.
2. Практика: пример использования cache: "no-store"
Давайте попробуем применить это на практике. Представим, что у нас есть серверный компонент, который отображает список последних сообщений чата. Мы хотим, чтобы каждый пользователь всегда видел только самые свежие сообщения.
Пример компонента:
// app/chat/page.jsx
export default async function ChatPage() {
const res = await fetch("https://example.com/api/messages", {
cache: "no-store"
});
const messages = await res.json();
return (
<div>
<h1>Чат</h1>
<ul>
{messages.map(msg => (
<li key={msg.id}>
<b>{msg.author}:</b> {msg.text}
</li>
))}
</ul>
</div>
);
}
Объяснение:
- Мы явно указываем { cache: "no-store" } в параметрах fetch.
- Теперь Next.js всегда будет делать новый запрос к API, даже если до этого кто-то уже заходил на эту страницу.
- Пользователь увидит только актуальные, свежие сообщения.
3. Как это влияет на поведение страницы
Сравнение с кешированием
| Параметр | Поведение |
|---|---|
(по умолчанию) |
Данные кешируются между запросами, обновляются только при пересборке или revalidate |
|
Данные всегда запрашиваются заново |
Влияние на производительность
Плюсы:
- Пользователь всегда видит актуальные данные.
- Нет риска показать устаревшую информацию.
Минусы:
- Каждый запрос к странице делает новый запрос к внешнему API или базе данных.
- При большом количестве пользователей или частых обновлениях это может увеличить нагрузку на сервер и замедлить загрузку страницы.
Когда использовать
Используйте cache: "no-store", если:
- Данные часто обновляются и должны быть максимально актуальными (например, чаты, корзины, админ-панели).
- Данные персональные или приватные (например, профиль пользователя).
- Вы разрабатываете функционал, где устаревшие данные недопустимы.
4. Полезные нюансы
Как это связано с вашим приложением
В нашем учебном приложении (например, "Список задач" или "Чат") вы можете встретить ситуации, когда после добавления, удаления или изменения задачи/сообщения пользователь должен сразу увидеть обновлённый список. Если бы мы использовали кешированные данные, пользователь мог бы увидеть устаревшую информацию — и это выглядело бы как баг.
С помощью cache: "no-store" мы гарантируем, что каждый раз после действий пользователя приложение показывает только свежие данные.
Совмещаем с другими опциями fetch
Иногда вместе с cache: "no-store" используют и другие параметры, например, next: { revalidate: 0 } (но это устаревший способ, начиная с Next.js 13+ рекомендуется использовать именно cache: "no-store").
Также, если вы используете авторизацию или персональные данные, можно добавить заголовки:
await fetch("/api/private", {
cache: "no-store",
headers: {
Authorization: `Bearer ${token}`
}
});
Влияние на Server Components и Client Components
Важно помнить:
- Опция cache: "no-store" работает только для серверных запросов (Server Components или Route Handlers).
- Если вы делаете запросы на клиенте (например, внутри useEffect в React-компоненте), это уже не контролируется Next.js, а зависит от браузера и самого fetch.
5. Типичные ошибки при использовании cache: "no-store"
Ошибка №1: Ожидание кеша при no-store
Иногда разработчики удивляются, что страница подтормаживает, ведь "раньше всё было быстро". Причина — отключено кеширование, и теперь каждый раз идёт запрос к серверу. Это не баг, а ожидаемое поведение.
Ошибка №2: Использование no-store для статичных данных
Нет смысла отключать кеш для данных, которые меняются раз в год (например, список стран или справочник валют). Это только нагружает сервер и замедляет загрузку страниц.
Ошибка №3: Забыли указать cache: "no-store" для динамических данных
Если вы забыли добавить опцию для часто меняющихся данных, пользователи будут видеть устаревшую информацию, пока не произойдёт пересборка страницы или revalidate.
Ошибка №4: Использование вместе с ISR/revalidate
Параметры cache: "no-store" и revalidate (ISR) взаимоисключающие. Если указать оба, будет работать только no-store — страница не будет кешироваться вообще.
Ошибка №5: Ожидание работы no-store в клиентских компонентах
Если вы используете fetch на клиенте (например, в useEffect), опция cache: "no-store" не влияет на Next.js — тут всё зависит от браузера.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ