Як працює інкрементальна статична регенерація (ISR) у Next.js
ISR (Інкрементальна Статична Регенерація) — це стратегія, яка поєднує переваги SSG та SSR. Сторінка генерується статично, але може оновлюватися у фоновому режимі через встановлений інтервал без повної перезбірки програми.
Проблема, яку вирішує ISR
Уявіть, що IT Lead має каталог проблем. Він оновлюється кілька разів на день. SSG не підходить, оскільки після додавання нової проблеми потрібно виконати повну next build. SSR не підходить, оскільки каталог однаковий для всіх користувачів, і немає сенсу генерувати його на кожен запит.
ISR вирішує цю дилему: сторінка статична, але знає, як оновити себе.
Як це працює
Початкова збірка
Сторінка генерується статично, так само як і SSG. HTML кешується.
Запит у межах вікна повторної перевірки
Користувач отримує кешовану версію сторінки. Без серверного рендерингу.
Запит після закінчення терміну повторної перевірки
Користувач все ще отримує кешовану версію (застарілу), але Next.js запускає регенерацію у фоновому режимі. Наступний користувач отримає оновлену сторінку.
Цей підхід називається stale-while-revalidate: надавайте застарілу версію, поки готується нова.
ISR у маршрутизаторі App
В маршрутизаторі App ISR налаштовується через параметр revalidate у fetch:
// app/problems/page.tsx
export default async function ProblemsPage() {
const res = await fetch('https://api.itlead.org/problems', {
next: { revalidate: 300 }
})
const problems = await res.json()
return (
<div>
<h1>Проблеми на IT Lead</h1>
<ul>
{problems.map((p: { id: string; name: string }) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
</div>
)
}revalidate: 300 означає: кешувати сторінку протягом 5 хвилин, потім оновлювати у фоновому режимі.
Налаштування на рівні сегмента
Ви можете встановити повторну перевірку для цілого маршруту:
// app/problems/layout.tsx
export const revalidate = 300
export default function ProblemsLayout({
children
}: {
children: React.ReactNode
}) {
return <>{children}</>
}Повторна перевірка за запитом
Замість інтервалу ви можете оновити сторінку за подією. Наприклад, після додавання нової проблеми:
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache'
import { NextResponse } from 'next/server'
export async function POST(request: Request) {
const { secret, path } = await request.json()
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ error: 'Неправильний секрет' }, { status: 401 })
}
revalidatePath(path)
return NextResponse.json({ revalidated: true })
}Або за допомогою тегів:
// Отримання даних з тегом
const res = await fetch('https://api.itlead.org/problems', {
next: { tags: ['problems'] }
})
// Інвалідність за тегом після зміни даних
revalidateTag('problems')На практиці:
Повторна перевірка за запитом є більш зручною, ніж підхід з інтервалом. Ви оновлюєте сторінку саме тоді, коли дані змінюються, а не після фіксованого періоду.
ISR у маршрутизаторі Pages (старий)
В маршрутизаторі Pages ISR активується шляхом додавання revalidate до getStaticProps:
// pages/problems.tsx
export async function getStaticProps() {
const res = await fetch('https://api.itlead.org/problems')
const problems = await res.json()
return {
props: { problems },
revalidate: 300
}
}Коли використовувати ISR
Добре для:
- Каталогів та списків (проблеми, продукти, курси)
- Контенту, що оновлюється кілька разів на день
- Сторінок, де кілька хвилин застарілості є прийнятними
- Великих сайтів, де повна перезбірка займає занадто багато часу
Не підходить для:
- Персоналізованого контенту (використовуйте SSR)
- Даних в реальному часі (використовуйте SSR або CSR з WebSocket)
- Контенту, який ніколи не змінюється (SSG достатньо)
Порівняння стратегій
| SSG | ISR | SSR | |
|---|---|---|---|
| Генерація | Під час збірки | Під час збірки + фонове оновлення | На кожен запит |
| Свіжість | Під час збірки | З затримкою (повторна перевірка) | Завжди актуально |
| Швидкість | Миттєво | Миттєво | Залежить від сервера |
| Перезбірка | Повна | Не потрібна | Не потрібна |
Корисні ресурси
- nextjs.org/docs — повторна перевірка даних
- Повторна перевірка за запитом — інвалідність на основі подій
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.