PurpleSchool — курсы программирования онлайн
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развития
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • Карьерные пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • PurpleSchool — курсы программирования онлайн
    • Сообщество
    • PurpleПлюс
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Серверные компоненты в Next.js 15: когда SSR лучше CSR и наоборот

    Серверные компоненты в Next.js 15: когда SSR лучше CSR и наоборот

    Аватар автора Серверные компоненты в Next.js 15: когда SSR лучше CSR и наоборот

    Антон Ларичев

    Иконка календаря19 марта 2026
    next.jsreacttypescriptmiddleИконка уровня middle
    Картинка поста Серверные компоненты в Next.js 15: когда SSR лучше CSR и наоборот

    Введение

    Серверные компоненты в Next.js 15 изменили подход к построению веб-приложений на React. С переходом на App Router все компоненты по умолчанию выполняются на сервере, что открывает новые возможности для оптимизации производительности и SEO. Но значит ли это, что клиентские компоненты больше не нужны?

    В этой статье разберём, как работают серверные и клиентские компоненты в Next.js 15, когда SSR (Server-Side Rendering) даёт преимущество перед CSR (Client-Side Rendering) и наоборот. Рассмотрим практические примеры и типичные ошибки.

    Как работают серверные компоненты в Next.js 15

    React Server Components (RSC) выполняются исключительно на сервере. Их код не попадает в JavaScript-бандл браузера, что уменьшает объём загружаемых данных. Сервер отрисовывает HTML и стримит его клиенту через React 18 Streaming.

    // app/products/page.tsx — серверный компонент (по умолчанию)
    async function ProductsPage() {
      // Прямой запрос к базе данных — безопасно, код не уходит в браузер
      const products = await db.product.findMany({
        where: { isActive: true },
        orderBy: { createdAt: 'desc' },
      });
    
      return (
        <main>
          <h1>Каталог товаров</h1>
          {products.map((product) => (
            <ProductCard key={product.id} product={product} />
          ))}
        </main>
      );
    }
    
    export default ProductsPage;
    

    Серверный компонент может напрямую обращаться к базе данных, файловой системе или внутренним API. Это устраняет необходимость в промежуточном API-слое для получения данных.

    Когда использовать клиентские компоненты

    Клиентские компоненты нужны для интерактивности: обработки событий, управления состоянием через хуки и работы с API браузера. Чтобы объявить компонент клиентским, добавьте директиву "use client" в начало файла.

    "use client";
    
    // components/SearchFilter.tsx — клиентский компонент
    import { useState, useTransition } from 'react';
    import { useRouter } from 'next/navigation';
    
    export function SearchFilter() {
      const [query, setQuery] = useState('');
      const [isPending, startTransition] = useTransition();
      const router = useRouter();
    
      const handleSearch = (value: string) => {
        setQuery(value);
        startTransition(() => {
          // Обновляем URL с параметрами поиска
          router.push(`/products?search=${encodeURIComponent(value)}`);
        });
      };
    
      return (
        <input
          type="text"
          value={query}
          onChange={(e) => handleSearch(e.target.value)}
          placeholder="Поиск товаров..."
          className={isPending ? 'opacity-50' : ''}
        />
      );
    }
    

    Какие задачи требуют директиву use client

    Используйте "use client", когда компоненту нужны:

    • Хуки React — useState, useEffect, useRef, useContext
    • Обработчики событий — onClick, onChange, onSubmit
    • API браузера — localStorage, window, navigator, IntersectionObserver
    • Сторонние библиотеки с клиентской логикой — карусели, модальные окна, дропдауны

    SSR vs CSR: сравнение подходов рендеринга

    Разница между SSR и CSR в Next.js 15 проявляется на нескольких уровнях.

    Производительность и время загрузки

    SSR через серверные компоненты выигрывает по метрике Time to First Byte (TTFB) и First Contentful Paint (FCP). Пользователь видит контент до загрузки JavaScript. CSR требует сначала загрузить и выполнить JS-бандл, и только потом начинается рендеринг.

    // SSR — данные приходят вместе с HTML
    // app/blog/[slug]/page.tsx
    async function BlogPost({ params }: { params: { slug: string } }) {
      const post = await getPostBySlug(params.slug);
    
      return (
        <article>
          <h1>{post.title}</h1>
          <div dangerouslySetInnerHTML={{ __html: post.content }} />
        </article>
      );
    }
    
    "use client";
    
    // CSR — данные загружаются после монтирования
    import { useEffect, useState } from 'react';
    
    function Dashboard() {
      const [stats, setStats] = useState(null);
    
      useEffect(() => {
        // Запрос выполняется в браузере после гидратации
        fetch('/api/stats')
          .then((res) => res.json())
          .then(setStats);
      }, []);
    
      if (!stats) return <p>Загрузка...</p>;
    
      return <StatsGrid data={stats} />;
    }
    

    SEO и индексация

    Серверный рендеринг критически важен для страниц, которые должны индексироваться поисковиками: блоги, каталоги, лендинги. Поисковые роботы получают готовый HTML без необходимости выполнять JavaScript.

    CSR подходит для закрытых разделов — личных кабинетов, дашбордов, админок, где SEO не играет роли.

    Как передать серверный компонент в клиентский

    Клиентские компоненты не могут импортировать серверные напрямую. Но есть паттерн композиции через children:

    // components/InteractiveWrapper.tsx
    "use client";
    
    import { useState } from 'react';
    
    export function InteractiveWrapper({ children }: { children: React.ReactNode }) {
      const [isOpen, setIsOpen] = useState(false);
    
      return (
        <div>
          <button onClick={() => setIsOpen(!isOpen)}>
            {isOpen ? 'Скрыть' : 'Показать'}
          </button>
          {isOpen && children}
        </div>
      );
    }
    
    // app/page.tsx — серверный компонент
    import { InteractiveWrapper } from '@/components/InteractiveWrapper';
    
    async function ServerContent() {
      const data = await fetchData(); // Выполняется на сервере
      return <pre>{JSON.stringify(data, null, 2)}</pre>;
    }
    
    export default function Page() {
      return (
        <InteractiveWrapper>
          <ServerContent />
        </InteractiveWrapper>
      );
    }
    

    Серверный компонент ServerContent передаётся как children в клиентский InteractiveWrapper. Рендеринг серверного компонента происходит на сервере, а клиентский добавляет интерактивность.

    Разница между SSR и серверными компонентами

    Важно не путать классический SSR и React Server Components. При SSR (через getServerSideProps в Pages Router) весь компонент рендерится на сервере, но затем полностью гидратируется на клиенте — весь JavaScript отправляется в браузер.

    Серверные компоненты в App Router работают иначе: их код вообще не попадает в клиентский бандл. Гидратация происходит только для клиентских компонентов, что существенно уменьшает размер JavaScript.

    // Pages Router (старый SSR) — код уходит в бандл
    export async function getServerSideProps() {
      const data = await fetchData();
      return { props: { data } };
    }
    
    // App Router (RSC) — код остаётся на сервере
    async function Page() {
      const data = await fetchData();
      return <div>{data.title}</div>;
    }
    

    Частые ошибки при работе с серверными компонентами

    Избыточное использование "use client". Не делайте клиентским весь компонент, если интерактивность нужна только в его части. Выносите интерактивную логику в отдельный мелкий клиентский компонент.

    Попытка использовать хуки в серверном компоненте. useState, useEffect и другие хуки работают только в клиентских компонентах. Если видите ошибку гидратации — проверьте, не забыли ли вы директиву "use client".

    Импорт серверного компонента в клиентский. Вместо прямого импорта используйте паттерн с children или props, как показано выше.

    Хранение секретов в серверных компонентах без проверки. Хотя код серверных компонентов не попадает в бандл, убедитесь, что вы не передаёте секреты через props в клиентские компоненты.

    Заключение

    Серверные компоненты в Next.js 15 — это не замена клиентских, а дополнение. Используйте SSR и серверные компоненты для контентных страниц, SEO-критичных разделов и работы с данными. Оставьте CSR и клиентские компоненты для интерактивных элементов интерфейса. Гибридный подход, где серверные и клиентские компоненты комбинируются через композицию — это оптимальная стратегия для современных Next.js-приложений.

    Иконка глаза213

    Комментарии

    0

    Постройте личный план изучения Next.js 15 - с нуля, React TypeScript, Hooks, SSR и CSS Grid до уровня Middle — бесплатно!

    Next.js 15 - с нуля, React TypeScript, Hooks, SSR и CSS Grid — часть карты развития Frontend

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Vue 3 и Pinia

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.9
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Nuxt

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Feature-Sliced Design

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.5
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста Монорепозиторий на Turborepo: как организовать фронт и бэк в одном репо
    Иконка аватараАнтон
    Иконка календаря10 апреля 2026
    typescriptreactnodejsmiddleИконка уровня middle

    Монорепозиторий на Turborepo: как организовать фронт и бэк в одном репо

    Разбираем, как настроить монорепозиторий на Turborepo для React и NestJS: структура проекта, общие типы, pipeline задач и кэширование сборки.

    Иконка чипа0
    Иконка глаза181
    Иконка комментариев0
    Картинка поста MCP-серверы: как подключить AI-ассистента к вашему проекту через Model Context Protocol
    Иконка аватараАнтон
    Иконка календаря17 апреля 2026
    ainodejstypescriptmiddleИконка уровня middle

    MCP-серверы: как подключить AI-ассистента к вашему проекту через Model Context Protocol

    MCP сервер позволяет AI-ассистенту работать с данными и инструментами вашего проекта через Model Context Protocol. Разбираем архитектуру и создаём сервер на TypeScript с нуля.

    Иконка чипа0
    Иконка глаза115
    Иконка комментариев0
    Картинка поста Как внедрить тесты в проект, где их никогда не было: пошаговая стратегия
    Иконка аватараАнтон
    Иконка календаря14 апреля 2026
    testingjavascripttypescriptmiddleИконка уровня middle

    Как внедрить тесты в проект, где их никогда не было: пошаговая стратегия

    Пошаговая стратегия внедрения тестов в существующий проект: с чего начать тестирование legacy-кода, какие тесты писать первыми и как настроить Vitest для JavaScript и TypeScript.

    Иконка чипа0
    Иконка глаза156
    Иконка комментариев0
    Иконка чипа0