Incremental Static Regeneration (ISR) — это механизм, позволяющий обновлять статические страницы на лету без необходимости полной пересборки сайта. Он особенно полезен при работе с динамическим контентом, где нужно сочетать преимущества статической генерации и актуальности данных. В экосистеме JavaScript и MDX ISR позволяет поддерживать страницы с документацией, блогами или любым контентом, написанным в формате Markdown/MDX, актуальными без длительных билдов.
В традиционном подходе к статической генерации (SSG) все страницы строятся во время сборки проекта. Это хорошо для небольших сайтов, но становится узким местом при больших объемах контента. ISR решает эту проблему следующим образом:
Статическая генерация при первом запросе: Страница создается как статическая во время сборки или при первом запросе.
Регистрация времени устаревания
(revalidate): Для каждой страницы указывается
период (в секундах), после которого следующая загрузка инициирует
пересоздание страницы.
Фоновое обновление контента: Новая версия страницы создается на сервере, а пользователи получают старую версию до завершения обновления. После завершения следующего запроса клиент получает уже свежую страницу.
Пример на JavaScript с использованием Next.js:
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { MDXRemote } from 'next-mdx-remote';
import { serialize } from 'next-mdx-remote/serialize';
export async function getStaticProps() {
const filePath = path.join(process.cwd(), 'content', 'article.mdx');
const source = fs.readFileSync(filePath, 'utf8');
const { content, data } = matter(source);
const mdxSource = await serialize(content, { scope: data });
return {
props: {
mdxSource,
frontMatter: data,
},
revalidate: 60, // ISR: обновление каждые 60 секунд
};
}
Ключевые моменты:
revalidate задает интервал обновления страницы.serialize.MDX позволяет встраивать React-компоненты прямо в Markdown. Использование ISR с MDX делает сайт интерактивным и динамически актуальным.
import { MDXRemote } from 'next-mdx-remote';
import { serialize } from 'next-mdx-remote/serialize';
import CustomButton from '../components/CustomButton';
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const components = { CustomButton };
export default function ArticlePage({ mdxSource }) {
return <MDXRemote {...mdxSource} components={components} />;
}
export async function getStaticProps() {
const filePath = path.join(process.cwd(), 'content', 'dynamic-article.mdx');
const source = fs.readFileSync(filePath, 'utf8');
const { content, data } = matter(source);
const mdxSource = await serialize(content, { scope: data });
return {
props: { mdxSource },
revalidate: 120, // Страница будет обновляться каждые 2 минуты
};
}
Важные аспекты:
CustomButton, могут быть
использованы внутри MDX.revalidate контролирует частоту обновления
контента.Для сайтов с большим количеством статических страниц (например, документация или блог) ISR помогает оптимизировать сборку:
getStaticPaths с
fallback:export async function getStaticPaths() {
const files = fs.readdirSync(path.join(process.cwd(), 'content'));
const paths = files.map((filename) => ({
params: { slug: filename.replace('.mdx', '') },
}));
return { paths, fallback: 'blocking' };
}
fallback: 'blocking' позволяет строить страницы на лету
при первом обращении, что совместимо с ISR.Комбинация с MDX: Каждая страница может иметь
собственный фронт-маттер и контент, автоматически сериализуемый с
serialize.
Производительность: ISR позволяет избежать полной пересборки сайта при изменении одного файла MDX, значительно ускоряя развертывание.
revalidate:
подбирается исходя из частоты обновления контента. Для документации
600–1800 секунд, для блога — 60–300 секунд.ISR объединяет лучшие практики статической генерации и динамического рендеринга, позволяя создавать современные сайты с MDX, которые одновременно быстрые и актуальные.