Пошук уроків, статей та іншого контенту
Налаштуєте автоматичне оновлення кешованих даних через заданий проміжок часу.
Time-based revalidation — це автоматичне оновлення кешованих даних через визначений проміжок часу.
Замість того щоб виконувати запит до джерела даних під час кожного відкриття сторінки, Next.js:
зберігає результат запиту в кеші;
використовує кешоване значення протягом заданого часу;
після завершення цього часу повторно отримує актуальні дані.
Такий підхід корисний для даних, які змінюються періодично, але не потребують оновлення після кожного запиту:
новини;
курси валют;
списки товарів;
статистика;
дані з зовнішнього API.
fetchУ серверному компоненті інтервал оновлення можна вказати в параметрі next.revalidate:
const response = await fetch("https://api.example.com/products", {
next: {
revalidate: 60,
},
});Значення 60 означає 60 секунд.
Протягом цього часу Next.js використовуватиме кешований результат. Після завершення інтервалу наступний запит може ініціювати отримання свіжих даних.
Створимо сторінку, яка отримує інформацію про репозиторій Next.js з GitHub API і оновлює її не частіше ніж раз на хвилину.
Файл app/page.tsx:
type Repository = {
name: string;
description: string | null;
stargazers_count: number;
forks_count: number;
html_url: string;
};
async function getRepository(): Promise<Repository> {
const response = await fetch(
"https://api.github.com/repos/vercel/next.js",
{
headers: {
Accept: "application/vnd.github+json",
},
next: {
revalidate: 60,
},
},
);
if (!response.ok) {
throw new Error("Не вдалося отримати дані репозиторію");
}
return response.json();
}
export default async function HomePage() {
const repository = await getRepository();
return (
<main>
<h1>{repository.name}</h1>
<p>{repository.description}</p>
<ul>
<li>Зірки: {repository.stargazers_count}</li>
<li>Форки: {repository.forks_count}</li>
</ul>
<a href={repository.html_url}>Відкрити на GitHub</a>
</main>
);
}Цей компонент виконується на сервері. Результат fetch кешується на 60 секунд.
Якщо сторінку відкриють кілька разів протягом першої хвилини, Next.js не виконуватиме зовнішній запит щоразу. Замість цього він використовуватиме кешовані дані.
Після завершення 60 секунд Next.js зможе отримати нову версію даних під час наступного звернення до сторінки.
Значення revalidate завжди вказується в секундах:
fetch(url, {
next: {
revalidate: 10,
},
});Поширені значення:
// Оновлення кожні 10 секунд
revalidate: 10
// Оновлення кожні 5 хвилин
revalidate: 300
// Оновлення щогодини
revalidate: 3600Інтервал потрібно вибирати відповідно до того, як часто фактично змінюються дані. Немає сенсу оновлювати щогодини дані, які змінюються кожні кілька секунд, або навпаки.
Окрім налаштування окремого fetch, можна задати інтервал для всього маршруту.
Файл app/news/page.tsx:
export const revalidate = 300;
type Article = {
id: number;
title: string;
};
async function getArticles(): Promise<Article[]> {
const response = await fetch("https://dummyjson.com/posts");
if (!response.ok) {
throw new Error("Не вдалося отримати статті");
}
const data: { posts: Article[] } = await response.json();
return data.posts;
}
export default async function NewsPage() {
const articles = await getArticles();
return (
<main>
<h1>Новини</h1>
<ul>
{articles.map((article) => (
<li key={article.id}>{article.title}</li>
))}
</ul>
</main>
);
}export const revalidate = 300 задає п'ятихвилинний інтервал для маршруту.
Це налаштування може застосовуватися до сторінки та її дочірніх компонентів у межах відповідного сегмента маршруту.
const response = await fetch(url, {
next: {
revalidate: 60,
},
});Використовуйте цей варіант, коли на одній сторінці різні джерела даних мають різні інтервали оновлення.
const productsResponse = await fetch(productsUrl, {
next: {
revalidate: 300,
},
});
const stockResponse = await fetch(stockUrl, {
next: {
revalidate: 30,
},
});У цьому прикладі:
товари оновлюються кожні 5 хвилин;
залишки на складі — кожні 30 секунд.
export const revalidate = 300;Цей варіант зручний, коли всі дані сторінки мають приблизно однакову частоту оновлення.
Припустимо, сторінка має таке налаштування:
export const revalidate = 60;Послідовність роботи виглядає так:
Перший запит отримує дані та зберігає їх у кеші.
Наступні запити протягом 60 секунд використовують кеш.
Після завершення 60 секунд Next.js вважає кеш застарілим.
Наступне звернення запускає оновлення даних.
Після успішного оновлення нові дані зберігаються в кеші.
У production-режимі Next.js може віддати попередню кешовану версію, поки у фоновому режимі отримує свіжі дані. Це дає змогу не змушувати користувача чекати завершення зовнішнього запиту.
Якщо оновлення завершиться помилкою, попередня успішна версія кешу може залишитися доступною, а Next.js спробує оновити її під час наступного запиту.
Якщо на сторінці є кілька кешованих запитів із різними інтервалами, сторінка може оновлюватися з урахуванням найменшого значення.
export const revalidate = 600;
async function getProducts() {
return fetch("https://api.example.com/products", {
next: {
revalidate: 300,
},
});
}
async function getCategories() {
return fetch("https://api.example.com/categories", {
next: {
revalidate: 60,
},
});
}У цьому прикладі один запит оновлюється кожні 5 хвилин, а інший — кожні 60 секунд. Для маршруту важливим стає найменший інтервал — 60 секунд.
Якщо дані потрібно оновлювати з різною частотою незалежно одне від одного, краще враховувати це під час структурування компонентів і маршрутів.
Поведінка кешу в режимі розробки може відрізнятися від production-режиму. Під час запуску проєкту командою:
npm run devNext.js може частіше виконувати запити, щоб спростити розробку та відображати зміни без тривалого очікування.
Перевіряти фактичну поведінку time-based revalidation потрібно у production-збірці:
npm run build
npm run startПід час вибору інтервалу враховуйте:
наскільки часто змінюються дані;
наскільки важливо показувати найновішу версію;
навантаження на зовнішній API;
обмеження rate limit зовнішнього сервісу;
допустиму затримку оновлення.
Наприклад:
// Дані, які змінюються рідко
next: {
revalidate: 3600,
}// Дані, які потрібно оновлювати частіше
next: {
revalidate: 30,
}Time-based revalidation не означає, що дані змінюються точно в момент завершення інтервалу. Інтервал визначає, коли кеш можна вважати застарілим і коли Next.js має виконати нове отримання даних.
revalidate у клієнтському компонентіНалаштування next.revalidate призначене для серверного fetch. Не потрібно переносити такий запит у компонент із директивою "use client".
"use client";Клієнтські компоненти використовують інший підхід до отримання та оновлення даних. Time-based revalidation у цьому уроці стосується серверних компонентів і серверного кешу Next.js.
Якщо вказано:
next: {
revalidate: 300,
}дані можуть залишатися кешованими до 5 хвилин. Не слід очікувати, що зміна у зовнішньому API одразу з'явиться на сторінці.
Якщо дані повинні оновлюватися після конкретної дії, одного time-based revalidation може бути недостатньо.
Інтервал у кілька секунд збільшує кількість запитів до джерела даних. Це може призвести до:
перевищення ліміту API;
повільнішої відповіді;
зайвого навантаження на сервер;
меншої ефективності кешу.
response.okНавіть якщо fetch завершився без мережевої помилки, сервер міг повернути HTTP-помилку. Тому результат потрібно перевіряти:
const response = await fetch(url, {
next: {
revalidate: 60,
},
});
if (!response.ok) {
throw new Error("Помилка отримання даних");
}У development-режимі кеш може поводитися не так, як у production. Для перевірки інтервалу використовуйте production-збірку:
npm run build
npm run startTime-based revalidation автоматично оновлює кеш через заданий інтервал.
Інтервал задається в секундах через next.revalidate.
revalidate можна налаштувати для окремого fetch або для всього маршруту.
Кешовані дані використовуються до завершення інтервалу.
Після завершення інтервалу Next.js отримує актуальні дані під час наступного звернення.
Для різних джерел даних можна встановлювати різні інтервали.
Поведінку кешу варто перевіряти у production-режимі.