SSG: Static Site Generation
Static Site Generation (SSG) — стратегия рендеринга, при которой HTML-страницы генерируются один раз во время сборки проекта и затем отдаются пользователям напрямую с CDN без обращения к серверу.
Зачем нужно
SSG обеспечивает максимально возможную скорость доставки контента: готовый HTML отдаётся с ближайшего CDN-узла без вычислений на сервере. TTFB (Time to First Byte) составляет 10-50 мс против 200-500 мс для SSR. Для сайтов с редко меняющимся контентом SSG — оптимальный выбор: блоги, документация, лендинги, маркетинговые сайты.
Где используется
- Документация (Docusaurus, VitePress, Nextra)
- Блоги и контентные сайты (Gatsby, Astro)
- Лендинги и маркетинговые страницы
- Portfolio-сайты
- Next.js
getStaticPropsдля страниц с нечастыми обновлениями
Как работает SSG
npm run build
↓
Сборщик выполняет getStaticProps/getStaticPaths
↓
Получает данные из CMS / API / файлов
↓
Рендерит каждую страницу в HTML-файл
↓
Результат: /about/index.html, /blog/post-1/index.html, ...
↓
Деплой на CDN (Vercel, Netlify, S3 + CloudFront)
↓
Пользователь запрашивает страницу → CDN отвечает HTML мгновенно
Next.js: getStaticProps и getStaticPaths
// pages/blog/[slug].jsx
// Какие страницы генерировать при сборке
export async function getStaticPaths() {
const posts = await fetchAllPosts; // запрос к CMS/API
return {
paths: posts.map(post => ({
params: { slug: post.slug },
})),
fallback: false, // 404 для несуществующих slug
// fallback: 'blocking' — генерирует новые страницы on-demand
// fallback: true — показывает loading state, генерирует в фоне
};
}
// Данные для каждой страницы
export async function getStaticProps({ params }) {
const post = await fetchPost(params.slug);
if (!post) {
return { notFound: true };
}
return {
props: { post },
// revalidate → превращается в ISR
// revalidate: 3600, // пересобирать не чаще раза в час
};
}
export default function BlogPost({ post }) {
return (
<article>
<h1>{post.title}</h1>
<time>{post.publishedAt}</time>
<div dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
</article>
);
}
Astro — SSG by default
---
// src/pages/blog/[slug].astro
// В Astro все страницы SSG по умолчанию
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render;
---
<html>
<head><title>{post.data.title}</title></head>
<body>
<h1>{post.data.title}</h1>
<Content />
</body>
</html>
Частые ошибки
- SSG для часто меняющихся данных — цены, остаток товаров, живые данные; используйте ISR или SSR.
- Огромное количество страниц при сборке — 100 000 страниц = очень долгий build; используйте
fallback: 'blocking'и ISR для генерации on-demand. - Забывают про
fallback— без настройкиfallbackновые страницы (добавленные после сборки) будут возвращать 404.
Связанные темы
- _MOC SPA
- CSR, SSR, SSG -- обзор подходов
- ISR -- Incremental Static Regeneration
- SSR -- Server Side Rendering
- Next.js -- обзор