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

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

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Серверные компоненты Next.js: внутреннее устройство

    Серверные компоненты Next.js: внутреннее устройство

    Аватар автора Серверные компоненты Next.js: внутреннее устройство

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

    Иконка календаря09 июля 2026
    Next.jsReactServer ComponentsRSCApp RoutermiddleИконка уровня middle
    Картинка поста Серверные компоненты Next.js: внутреннее устройство

    Введение

    Серверные компоненты React (RSC) стали одним из ключевых нововведений в экосистеме Next.js. В отличие от классического SSR, они выполняются исключительно на сервере и никогда не попадают в браузер. Это меняет фундаментальные принципы построения приложений — граница между сервером и клиентом становится явной частью архитектуры.

    В этой статье разберём, как серверные компоненты устроены изнутри: что происходит на уровне React runtime, как данные передаются клиенту и почему этот подход быстрее традиционного SSR.

    Серверные и клиентские компоненты: ключевые отличия

    В Next.js App Router все компоненты по умолчанию являются серверными. Чтобы сделать компонент клиентским, нужно явно добавить директиву 'use client' в начало файла.

    // Серверный компонент — выполняется только на сервере
    async function UserProfile({ userId }: { userId: string }) {
      // Прямой запрос к базе данных без API-слоя
      const user = await db.users.findById(userId);
    
      return (
        <div>
          <h2>{user.name}</h2>
          <ClientSideWidget data={user.preferences} />
        </div>
      );
    }
    
    'use client';
    
    // Клиентский компонент — работает и на сервере при гидратации, и в браузере
    import { useState } from 'react';
    
    function ClientSideWidget({ data }: { data: Preferences }) {
      const [expanded, setExpanded] = useState(false);
    
      return (
        <button onClick={() => setExpanded(!expanded)}>
          {expanded ? 'Скрыть' : 'Показать'}
        </button>
      );
    }
    

    Серверный компонент может импортировать клиентский, но не наоборот. Это однонаправленная граница.

    RSC Payload: формат передачи данных

    Когда Next.js рендерит страницу с серверными компонентами, он не отправляет только готовый HTML. Вместо этого создаётся специальный формат — RSC Payload.

    RSC Payload — это бинарный поток данных, похожий на JSON, но расширенный. Он содержит:

    • Дерево компонентов в сериализованном виде
    • Пропсы и данные, полученные на сервере
    • Ссылки на клиентские компоненты (module references)
    • Данные для Suspense и стриминга
    // Упрощённое представление RSC Payload
    1:{"type":"div","props":{"className":"wrapper"},"children":["$2"]}
    2:{"type":"$Lc/components/Button.js","props":{"label":"Нажми"},"children":null}
    

    В реальности формат использует числовые идентификаторы для ссылок и передаётся потоком по мере выполнения компонентов.

    Как Next.js обрабатывает запрос

    Шаг 1: получение запроса

    Next.js принимает HTTP-запрос и на основе файловой системы App Router определяет, какие layout и page нужно рендерить.

    Шаг 2: выполнение серверных компонентов

    React запускает рендеринг дерева компонентов. Каждый серверный компонент может быть async и выполнять запросы к БД, внешним API или файловой системе.

    // Параллельные запросы данных — не блокируют друг друга
    async function Dashboard() {
      const [stats, notifications] = await Promise.all([
        fetchStats(),
        fetchNotifications(),
      ]);
    
      return (
        <main>
          <StatsPanel data={stats} />
          <NotificationList items={notifications} />
        </main>
      );
    }
    

    Шаг 3: стриминг через Suspense

    Next.js поддерживает потоковую передачу HTML. Содержимое внутри <Suspense> отправляется клиенту по мере готовности, не блокируя отрисовку остальной страницы.

    import { Suspense } from 'react';
    
    async function Page() {
      return (
        <div>
          <Header />
          {/* Стримится отдельно, не задерживает Header */}
          <Suspense fallback={<Skeleton />}>
            <SlowDataComponent />
          </Suspense>
        </div>
      );
    }
    

    Шаг 4: гидратация на клиенте

    Браузер получает HTML и RSC Payload одновременно. React использует payload для восстановления дерева компонентов — гидратируются только клиентские компоненты, серверные повторно не рендерятся.

    Кэширование и дедупликация запросов

    fetch внутри серверных компонентов автоматически дедуплицируется в рамках одного запроса. Если несколько компонентов вызовут один и тот же URL, реальный HTTP-запрос выполнится только один раз.

    // Оба компонента на одной странице сделают только один HTTP-запрос
    async function ComponentA() {
      const data = await fetch('https://api.example.com/config');
      return <div>{/* использование data */}</div>;
    }
    
    async function ComponentB() {
      // Результат берётся из кэша дедупликации
      const data = await fetch('https://api.example.com/config');
      return <div>{/* использование data */}</div>;
    }
    

    Частые ошибки

    Использование браузерных API в серверных компонентах

    Серверные компоненты выполняются в Node.js, где нет window, document или localStorage.

    // Ошибка: window не существует в серверном окружении
    function BadComponent() {
      const width = window.innerWidth; // ReferenceError
      return <div>{width}</div>;
    }
    
    // Правильно: браузерный API выносится в клиентский компонент
    'use client';
    function GoodComponent() {
      const [width, setWidth] = useState(0);
      useEffect(() => {
        setWidth(window.innerWidth);
      }, []);
      return <div>{width}</div>;
    }
    

    Передача несериализуемых пропсов

    Пропсы из серверного компонента в клиентский должны сериализоваться в JSON. Функции и экземпляры классов передать нельзя.

    // Ошибка: функция не сериализуется через RSC Payload
    <ClientComponent onClick={() => console.log('click')} />
    
    // Правильно: обработчик определяется внутри клиентского компонента
    <ClientComponent itemId={item.id} />
    

    Избыточное использование 'use client'

    Добавление 'use client' везде по привычке из Pages Router лишает вас преимуществ RSC. Выносите в клиентские компоненты только то, что требует интерактивности или браузерных API. Всё остальное должно оставаться серверным.

    Заключение

    Серверные компоненты Next.js — это не просто SSR с другим синтаксисом. Это новая архитектурная модель, где граница сервер/клиент стала явной частью кода. RSC Payload, стриминг через Suspense и автоматическая дедупликация запросов позволяют строить быстрые приложения с минимальным JavaScript на клиенте.

    Главные выводы:

    • Серверные компоненты выполняются только на сервере и не увеличивают JS-бандл
    • RSC Payload передаёт сериализованное дерево компонентов, а не только HTML
    • Стриминг позволяет отображать части страницы по мере их готовности
    • Пропсы между серверными и клиентскими компонентами обязаны быть сериализуемы в JSON
    Иконка глаза615

    Комментарии

    0

    Постройте личный план изучения React state менеджер Zustand до уровня Middle — бесплатно!

    React state менеджер Zustand — часть карты развития Frontend

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

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

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

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

    Vue 3 и Pinia

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

    Next.js - с нуля

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

    Feature-Sliced Design

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

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

    Картинка поста React useState и useEffect: полное руководство 2024
    Иконка аватараАнтон
    Иконка календаря29 июля 2026
    ReactuseStateuseEffect+ 3juniorИконка уровня junior

    React useState и useEffect: полное руководство 2024

    Разбираем useState и useEffect с нуля: как управлять состоянием и побочными эффектами в React-компонентах с реальными примерами.

    Иконка чипа0
    Иконка глаза957
    Иконка комментариев0
    Картинка поста CI/CD: что это такое и как настроить пайплайн с нуля
    Иконка аватараАнтон
    Иконка календаря21 августа 2026
    CI/CDDevOpsGitHub Actions+ 2middleИконка уровня middle

    CI/CD: что это такое и как настроить пайплайн с нуля

    CI/CD — что это простыми словами и как настроить автоматическую сборку, тестирование и деплой кода на примере GitHub Actions и GitLab CI.

    Иконка чипа0
    Иконка глаза58
    Иконка комментариев0
    Картинка поста PostgreSQL vs MySQL: что выбрать для проекта
    Иконка аватараАнтон
    Иконка календаря13 августа 2026
    PostgreSQLMySQLбазы данных+ 3middleИконка уровня middle

    PostgreSQL vs MySQL: что выбрать для проекта

    PostgreSQL vs MySQL — сравниваем архитектуру, производительность, типы данных и транзакции, чтобы выбрать подходящую БД для вашего проекта.

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