← Назад к вопросам

Что такое ISR?

1.8 Middle🔥 121 комментариев
#Node.js и JavaScript#Кэширование и производительность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ISR (Incremental Static Regeneration) в Next.js

ISR — это одна из самых мощных фишек Next.js для создания высокопроизводительных статических сайтов, которые автоматически обновляются. Это гибрид между статическим сайтом и динамическим приложением.

Что такое ISR?

ISR (Incremental Static Regeneration) — это стратегия кэширования в Next.js, которая позволяет:

  • Генерировать статические страницы при билде
  • Автоматически регенерировать эти страницы в background
  • Обновлять только те страницы, которые изменились
  • Не требует перестройки всего проекта

Задача была решена в Next.js 9.5, и это революционизировало подход к dynamic контенту.

Как работает ISR

// pages/blog/[slug].tsx
export async function getStaticProps({ params }) {
  const post = await fetchBlogPost(params.slug);
  
  return {
    props: {
      post,
    },
    revalidate: 60,  // ISR: регенерировать каждые 60 секунд
  };
}

export async function getStaticPaths() {
  // На время билда генерируем популярные посты
  const posts = await fetchPopularPosts();
  
  return {
    paths: posts.map(p => ({ params: { slug: p.slug } })),
    fallback: 'blocking',  // Новые посты генерируются on-demand
  };
}

export default function BlogPost({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

Режимы ISR

1. Time-based ISR (Самый популярный)

return {
  props: { data },
  revalidate: 3600,  // Регенерировать каждый час
};

Это означает:

  • Первый пользователь получает кэшированную версию
  • На background запускается регенерация
  • Следующие пользователи через час получат новую версию

2. On-demand ISR (API-triggered)

// pages/api/revalidate.ts
export default async function handler(req, res) {
  // Проверка секретного токена
  if (req.query.secret !== process.env.REVALIDATE_SECRET) {
    return res.status(401).json({ message: 'Invalid token' });
  }

  try {
    // Регенерировать конкретную страницу
    await res.revalidate('/blog/my-post');
    return res.json({ revalidated: true });
  } catch (err) {
    return res.status(500).send('Error revalidating');
  }
}

Так можно регенерировать страницу по запросу (например, после обновления в CMS):

# Когда пост обновлен в CMS, вызываем
curl -X POST "https://example.com/api/revalidate?secret=TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"path": "/blog/updated-post"}'

3. Fallback режимы

return {
  paths: somePages,
  fallback: false,      // 404 если страницы нет
  fallback: true,       // SSR если страницы нет, потом кэшируется
  fallback: 'blocking', // SSR на сервере, потом кэшируется
};

Практические примеры

Пример 1: Блог с часто обновляемыми постами

export async function getStaticProps({ params }) {
  const post = await db.posts.findBySlug(params.slug);
  
  // Популярные посты (очень часто читаемые) обновляются каждые 5 минут
  const isPopular = post.views > 10000;
  const revalidate = isPopular ? 300 : 3600;  // 5 min или 1 hour
  
  return {
    props: { post },
    revalidate,
  };
}

Пример 2: E-commerce каталог товаров

export async function getStaticProps({ params }) {
  const product = await fetchProduct(params.id);
  
  // Цены часто меняются — 15 минут
  // Описание редко меняется — 1 день
  return {
    props: { product },
    revalidate: 15 * 60,
  };
}

Пример 3: Интеграция с CMS

// pages/api/revalidate-webhook.ts
export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).end();
  }
  
  // Webhook от Sanity CMS при обновлении контента
  const { slug } = req.body;
  
  try {
    await res.revalidate(`/blog/${slug}`);
    return res.json({ message: `Revalidated /blog/${slug}` });
  } catch (e) {
    return res.status(500).send('Error revalidating');
  }
}

Теперь в Sanity настраиваем webhook на этот endpoint, и при каждом обновлении поста он автоматически регенерируется.

ISR vs SSR vs SSG

ПодходBuild timeRuntimeCacheBest for
SSG (Static Generation)ДолгоБыстроforeverStatic контент
ISRБыстроБыстроrevalidateDynamic контент с кэшем
SSR (Server-Side Render)-МедленноnoneReal-time контент

Преимущества ISR

  1. Скорость — статические файлы раздаются из CDN со скоростью света
  2. Масштабируемость — не нужно вычислять для каждого пользователя
  3. Отказоустойчивость — если БД упадет, старая версия все еще работает
  4. SEO — поисковики видят готовый HTML, а не JavaScript
  5. Cost — статический хостинг намного дешевле, чем server-render

Недостатки ISR

  1. Delay — между обновлением и появлением на сайте есть lag
  2. Сложность — нужно управлять revalidate интервалами
  3. Build size — для сайта с миллионом страниц problematic
  4. On-demand limited — не безлимитные регенерации (на Vercel есть лимиты)

ISR vs On-Demand ISR

Time-based ISR:

revalidate: 60  // Каждый час проверяет

Проблема: если контент обновился за 30 минут до revalidate, то пользователь еще 30 минут видит старую версию.

On-Demand ISR:

await res.revalidate('/path')

Решение: мгновенно регенерировать по запросу из CMS webhook.

Лучшая практика: комбинировать обе

return {
  props: { post },
  revalidate: 3600,  // fallback на регенерацию каждый час
};
// + webhook для мгновенной регенерации при изменении

Хостинг на Vercel

Vercel оптимизирована для ISR:

  • Автоматические регенерации работают в background
  • Не нужен долгоживущий server
  • Кэш хранится на Edge locations (CDN)
  • Есть dashboard для мониторинга
// На Vercel это просто работает
export async function getStaticProps() {
  return {
    props: {},
    revalidate: 60,
  };
}

ISR на других хостингах

Другие платформы требуют self-hosted сервер для фоновых регенераций:

  • Railway, Render, Dokku
  • Используйте On-Demand ISR вместе с webhooks
// Без фоновых регенераций используйте on-demand
await res.revalidate('/path');

Заключение

ISR — это лучший выбор для большинства современных веб-приложений:

  • Нужна скорость SSG
  • Но контент динамический
  • И не нужен real-time update

ISR позволяет получить лучшее из обоих миров: производительность статических сайтов с гибкостью динамического контента.