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
    Иконка глаза4

    Комментарии

    0

    Постройте личный план изучения Nuxt - fullstack Vue фреймворк до уровня Middle — бесплатно!

    Nuxt - fullstack Vue фреймворк — часть карты развития Frontend

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

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

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

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

    Основы разработки

    Антон Ларичев
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    бесплатно
    Подробнее
    изображение курса

    Angular

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

    Feature-Sliced Design

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

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

    Картинка поста CI/CD пайплайн в GitHub Actions для Next.js: полный гайд
    Иконка аватараАнтон
    Иконка календаря18 июня 2026
    GitHub ActionsCI/CDNext.js+ 2middleИконка уровня middle

    CI/CD пайплайн в GitHub Actions для Next.js: полный гайд

    CI/CD пайплайн в GitHub Actions для Next.js: настройка автоматической сборки, тестирования и деплоя приложения с примерами workflow-файлов и разбором типичных ошибок.

    Иконка чипа0
    Иконка глаза375
    Иконка комментариев0
    Картинка поста Тестирование React-компонентов с React Testing Library
    Иконка аватараАнтон
    Иконка календаря07 июля 2026
    reacttestingreact-testing-library+ 2middleИконка уровня middle

    Тестирование React-компонентов с React Testing Library

    React Testing Library — инструмент для тестирования React-компонентов через поведение пользователя, а не детали реализации. Примеры, паттерны, частые ошибки.

    Иконка чипа0
    Иконка глаза93
    Иконка комментариев0
    Картинка поста Микрофронтенды и Module Federation: подходы и реализация
    Иконка аватараАнтон
    Иконка календаря06 июля 2026
    микрофронтендыmodule-federationwebpack+ 2seniorИконка уровня senior

    Микрофронтенды и Module Federation: подходы и реализация

    Микрофронтенды с Module Federation: как разбить монолитный фронтенд на независимые части, которые деплоятся и разрабатываются отдельно.

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