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

В чем разница между SSR mode?

2.0 Middle🔥 231 комментариев
#Архитектура и паттерны

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

В чем разница между SSR mode?

SSR (Server-Side Rendering) имеет несколько режимов выполнения, которые критически влияют на производительность, масштабируемость и пользовательский опыт приложения. Понимание различий между ними важно для правильной архитектуры.

Основные SSR режимы

1. Static Generation (SSG)

Static Generation - страницы генерируются во время сборки (build time):

// Next.js пример
export async function getStaticProps() {
  const posts = await fetchPosts();
  return {
    props: { posts },
    revalidate: 86400 // ISR: переизвлечь через 24 часа
  };
}

export default function Blog({ posts }) {
  return <div>{posts.map(p => <p key={p.id}>{p.title}</p>)}</div>;
}

// Результат: HTML файл генерируется один раз и переиспользуется для всех пользователей

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

  • Максимальная скорость (можно кэшировать на CDN)
  • Минимальная нагрузка на сервер
  • Отличная производительность

Недостатки:

  • Долгое время сборки для больших сайтов (тысячи страниц)
  • Сложно обновлять часто меняющиеся данные
  • Все пользователи видят одинаковый контент

2. Server-Side Rendering (SSR)

Server-Side Rendering - страницы генерируются для каждого запроса на сервере:

// Next.js пример
export async function getServerSideProps(context) {
  const { userId } = context.params;
  const user = await fetchUser(userId);
  
  return {
    props: { user },
    revalidate: 0 // Не кэшировать
  };
}

export default function UserProfile({ user }) {
  return <div>Welcome {user.name}!</div>;
}

// Результат: HTML генерируется для каждого запроса

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

  • Свежие данные для каждого пользователя
  • Подходит для динамического контента
  • Хорошо для SEO (поисковики видят полный HTML)
  • Может быть персонализировано

Недостатки:

  • Медленнее чем SSG (генерация для каждого запроса)
  • Высокая нагрузка на сервер при популярности
  • Время отклика зависит от скорости БД

3. Incremental Static Regeneration (ISR)

ISR - гибридный подход: генерирует статичные страницы, но переизвлекает их в фоне:

export async function getStaticProps() {
  const posts = await fetchPosts();
  return {
    props: { posts },
    revalidate: 60 // Переизвлечь страницу через 60 секунд
  };
}

// Первый запрос: быстро возвращает старый HTML
// В фоне: генерирует новый HTML на основе свежих данных
// Второй запрос: возвращает новый HTML

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

  • Быстрота SSG в большинстве случаев
  • Свежесть данных (через определенный интервал)
  • Масштабируется без проблем

Недостатки:

  • Может быть задержка в обновлении (до revalidate интервала)
  • Требует настройки времени переизвлечения
  • Нужна фоновая работа сервера

Практическое сравнение

// Сценарий 1: Блог с редко обновляемыми постами
// Решение: SSG + ISR
export async function getStaticProps() {
  const posts = await fetchPosts();
  return {
    props: { posts },
    revalidate: 3600 // Обновлять раз в час
  };
}

// Сценарий 2: Профиль пользователя (персональный контент)
// Решение: SSR
export async function getServerSideProps(context) {
  const { userId } = context.params;
  const user = await fetchUser(userId);
  return {
    props: { user }
  };
}

// Сценарий 3: Каталог товаров (много страниц, редкие обновления)
// Решение: SSG + ISR
export async function getStaticProps(context) {
  const { productId } = context.params;
  const product = await fetchProduct(productId);
  return {
    props: { product },
    revalidate: 86400 // Обновлять раз в день
  };
}

export async function getStaticPaths() {
  // Какие пути генерировать при сборке
  return {
    paths: [
      { params: { productId: '1' } },
      { params: { productId: '2' } }
    ],
    fallback: 'blocking' // При запросе неизвестного пути - SSR
  };
}

Client-Side Rendering (CSR)

Хотя это не SSR, важно понимать отличие:

// CSR: рендер происходит в браузере
import { useEffect, useState } from 'react';

export default function Page() {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch('/api/data')
      .then(r => r.json())
      .then(setData);
  }, []);
  
  if (!data) return <div>Loading...</div>;
  return <div>{data.title}</div>;
}

// Проблемы:
// - Пустой HTML изначально (плохо для SEO)
// - Медленнее чем SSR (двойной запрос: HTML + API)
// - Может быть видна процесс загрузки

Performance сравнение

// Метрики для типичной страницы:

// SSG: 50ms - 100ms (из кэша CDN)
const ssg = {
  ttfb: '50ms', // Time To First Byte
  fcp: '80ms',  // First Contentful Paint
  lcp: '150ms'  // Largest Contentful Paint
};

// ISR: 50ms (первый раз), затем обновляется
const isr = {
  ttfb: '50ms (кэш) или 500ms (регенерация)',
  fcp: '80ms (кэш) или 600ms (регенерация)',
  lcp: '150ms (кэш) или 700ms (регенерация)'
};

// SSR: 200ms - 1000ms (зависит от БД)
const ssr = {
  ttfb: '300-500ms',
  fcp: '400-600ms',
  lcp: '600-1000ms'
};

// CSR: 100ms (HTML) + 300ms (API) = 400ms+
const csr = {
  ttfb: '100ms',
  fcp: '500-800ms (из-за JS выполнения)',
  lcp: '700-1200ms'
};

Выбор режима в Next.js

// pages/blog/[slug].tsx

// Вариант 1: SSG с ISR
export async function getStaticProps(context) {
  const post = await fetchPost(context.params.slug);
  return {
    props: { post },
    revalidate: 60 // Переизвлечь через минуту
  };
}

export async function getStaticPaths() {
  return {
    paths: [{ params: { slug: 'hello-world' } }],
    fallback: 'blocking' // На неизвестных путях: SSR
  };
}

// Вариант 2: SSR
export async function getServerSideProps(context) {
  const post = await fetchPost(context.params.slug);
  return { props: { post } };
}

// Выбор зависит от:
// - Частоты обновлений
// - Количества уникальных страниц
// - Требований к свежести данных
// - Нагрузке на сервер

Рекомендации

Используй SSG + ISR для:

  • Блогов и документации
  • Каталогов товаров
  • Статичного контента с редкими обновлениями
  • Когда нужна максимальная скорость

Используй SSR для:

  • Персонального контента (профили пользователей)
  • Данных зависящих от cookies/headers
  • Часто меняющихся данных
  • Когда нужна максимальная свежесть

Используй CSR для:

  • Админ-панелей (не нужен SEO)
  • Интерактивных приложений
  • Когда можно ждать загрузки JS

Гибридный подход (современный стандарт)

// Лучший паттерн: SSG/ISR + гидрация + Client-Side обновления
export async function getStaticProps() {
  // SSG для быстрого первого запроса
  const initialData = await fetchData();
  return {
    props: { initialData },
    revalidate: 3600
  };
}

export default function Page({ initialData }) {
  const [data, setData] = useState(initialData);
  
  // Обновляем данные в браузере, если нужно
  useEffect(() => {
    const interval = setInterval(
      () => fetchFreshData().then(setData),
      60000 // Проверять каждую минуту
    );
    return () => clearInterval(interval);
  }, []);
  
  return <div>{data.title}</div>;
}

// Результат: быстрая доставка + свежие данные = лучший UX

Итоговая таблица

РежимСкоростьСвежестьСложностьМасштабируемость
SSGОтличнаяНизкаяПростойОтличная
ISRОтличнаяХорошаяСреднийОтличная
SSRХорошаяОтличнаяСреднийСредняя
CSRСредняяХорошаяПростойХорошая

Правильный выбор SSR режима - один из ключей к высокопроизводительному приложению.

В чем разница между SSR mode? | PrepBro