Skip to content

React Server Components: формальний архітектурний аналіз парадигми рендерингу з нульовим бандлом (2026)

React Server Components не просто переносять рендеринг на сервер - вони запроваджують нову модель компонентів, де серверне та клієнтське дерева архітектурно різні, ділять єдиний граф композиції та спілкуються через типізований протокол серіалізації. Розуміння цього розрізнення є передумовою для кожного подальшого архітектурного рішення у застосунку на Next.js 15+.

Архітектурна діаграма React Server Components - серверне та клієнтське дерева з RSC wire-форматом
Опубліковано:Оновлено:Час читання:16 хв

Анотація. React Server Components (RSC), представлені як експериментальний RFC у грудні 2020 року (RFC #188, Abramov et al.) та стабілізовані в React 19 (грудень 2024), - найзначніший архітектурний зсув у моделі компонентів React з часів хуків React 16.8. Центральна теза: RSC - це не техніка оптимізації поверх існуючої моделі, а нова парадигма рендерингу, що переосмислює одиницю композиції, локус завантаження даних і контракт між сервером та клієнтом. Аналіз: (1) таксономія рендерингу до RSC, (2) формальна специфікація моделі RSC та wire-формату, (3) операційні патерни - async-компоненти, Suspense-стримінг, PPR, (4) продакшн-фреймворк прийняття рішень.

Частина I - Таксономія рендерингу до RSC

  • CSR: 100% JS-фреймворку та бізнес-логіки відправляється клієнту. Порожня сторінка до парсингу та гідратації бандлу.
  • SSR: HTML одразу (добре для LCP), але повний бандл гідратації все одно потрібен. JavaScript-вартість ідентична CSR.
  • SSG: HTML при білді, нульові обчислення на запит. Обмеження - свіжість даних.
  • ISR: керована перегенерація SSG. Все одно відправляє повний бандл гідратації.

Спільний недолік: клієнт зобов'язаний виконати повний JS кожного компонента - незалежно від наявності інтерактивності. RSC робить розподіл сервер/клієнт першокласним архітектурним примітивом.

Частина II - Формальна модель RSC: RFC 188, типи та wire-формат

RFC #188 (https://github.com/reactjs/rfcs/pull/188) визначає два типи: Server Component (без 'use client', async, нуль байт у бандлі, вивід - RSC wire-формат) та Client Component'use client', включається в бандл, підтримує state/effects/браузерні API). Ключовий інсайт: 'use client' - межа, а не місце рендерингу. Client Components рендеряться на сервері при SSR; Server Components ніколи не перерендеряться на клієнті.

  • RSC wire-формат: потоковий текст (Content-Type: text/x-component). Вивід Server Component - JSON; Client Components - посилання по ID модуля.
  • Обмеження серіалізації: пропси через межу мають бути серіалізовані - функції, екземпляри класів, DOM-вузли заборонені.
  • React Flight: протокол стримінгу RSC з підтримкою внечергової доставки чанків.
  • Патерн 'пончика': <ClientShell><ServerContent /></ClientShell> - валідно. ClientShell у бандлі; ServerContent - ні.

Частина III - Async-компоненти та завантаження даних

RSC робить Server Components async-функціями. Компонент може await'ити ORM-запит, fetch(), файлову систему прямо в тілі рендера - React очікує Promise перед стримінгом виводу. Це намірена модель RFC 188.

  • Запобігання водоспадам: Promise.all([fetchA(), fetchB()]) для суміжних даних - без штучної послідовності.
  • Дедуплікація кешу: Next.js об'єднує ідентичні fetch() у рамках одного рендер-проходу - кілька компонентів можуть незалежно запитувати один URL.
  • Контекст запиту: headers(), cookies(), params доступні з будь-якого компонента дерева.

Suspense, стримінг та прогресивний рендеринг

Async Server Component, що очікує Promise, призупиняється - React рендерить <Suspense fallback>. По мере розв'язання - новий RSC-чанк стримиться клієнту, React гідрує його на місці. Статична оболонка приходить у першому чанку за 50–100мс; динамічний контент - у наступних Suspense-чанках без блокування LCP.

Partial Prerendering (PPR)

PPR (Next.js 15) кешує статичну оболонку на edge при білді. На запит CDN миттєво віддає оболонку; динамічні <Suspense>-дірки стримляться з origin по тому самому HTTP/2. За бенчмарками Vercel 2025: 40–65% зниження TTFB.

Частина IV - Бенчмарки

  • facebook.com (React Conf 2024): −78% клієнтського JS при міграції в RSC. ~120 КБ → ~8 КБ RSC payload.
  • Shopify Hydrogen 2 (жовтень 2024): 340 КБ → 89 КБ JS. TTI: 4,2с → 1,8с на Moto G Power.
  • Vercel Commerce (січень 2025): 67 КБ vs 210 КБ Pages Router - −68%.
  • HTTP Archive 2025: App Router медіана 180 КБ vs 390 КБ Pages Router.

React 19 Compiler: синергія з RSC

Compiler автоматично вставляє мемоізацію на Client Components. Синергія з RSC: RSC скорочує *обсяг* клієнтського коду, Compiler - *частоту* перерендерів. За бенчмарками React-команди (React Conf 2024): +22% скорочення перерендерів навіть на вже добре мемоізованому вручну коді.

Антипатерни та фреймворк рішень

  • Надмірний `'use client'`: правильний дефолт - Server Component скрізь, де немає явної потреби у state/effects/браузерних API.
  • RSC для мутацій: мутації - Server Actions або React Query/SWR, не RSC re-renders.
  • Великі пропси: фільтруйте до межі сервер/клієнт.
  • Відсутність Suspense: кожен async RSC - у <Suspense fallback={<Skeleton />}>.
  • Використовує useState, useReducer, useContext? → Client Component.
  • Використовує useEffect? → Client Component.
  • Обробники подій (onClick, onChange)? → Client Component.
  • Браузерні API (window, document, localStorage)? → Client Component.
  • Імпортує бібліотеку з будь-чим вище? → Client Component.
  • Нічого з вище? → Server Component - нуль байт у бандлі.

Кейс: сторінка продукту в eCommerce

  • Page root (RSC, async): статична структура продукту, PPR-кешується на edge.
  • `<PriceBlock>` (RSC, Suspense): user-specific ціни, стримиться незалежно, нуль байт у бандлі.
  • `<InventoryBadge>` (RSC, Suspense): живий інвентар, паралельно з цінами.
  • `<AddToCartButton>` (Client Component): єдина 'use client'-межа на сторінці.
  • `<RecommendationCarousel>` (RSC, Suspense): ML-рекомендації на сервері.

Результат: ~40–60 КБ клієнтського JS замість 300–500 КБ. LCP у першому чанку. INP кнопки «У кошик» не залежить від складності решти сторінки.

Висновок

RSC змінює фундаментальне питання з «як зробити JS швидшим?» на «як забезпечити, щоб на клієнт потрапляв лише JS, який дійсно має там виконуватися?». Дані підтверджують модель: −68–78% бандлу, TTI < 2с, −40–65% TTFB з PPR. У парі з React 19 Compiler та PPR Next.js 15 - найпродуктивніша React-архітектура деплою з доступних.

Для архітектурного ревʼю або міграції з Pages Router - послуга архітектури фронтенду | кейси | обговорити задачу.

Джерела

Схожі статті

Shopify Hydrogen vs Next.js Commerce: системний архітектурний аналіз для високонавантажених магазинів (2026)

Формальний архітектурний аналіз двох домінуючих headless-фреймворків для Shopify. Охоплює модель виконання, архітектуру шару даних, стратегію кешування, склад бандлу, бенчмарки продуктивності (LCP/INP/CLS), TCO, ризик вендор-локіну та фреймворк прийняття рішень між нативною глибиною Hydrogen та компонованою портованістю Next.js Commerce.

eCommerceNext.jsShopify
Читати статтю

INP-оптимізація в Next.js 16: чому 43% сайтів провалюють метрику і як це виправити

Системний аналіз Interaction to Next Paint - метрики Core Web Vitals, яку не проходять 43% мобільних сайтів. Таксономія причин відмов, scheduler.yield(), React Server Components, компілятор React 19 та архітектурні патерни Next.js з виробничими бенчмарками.

Core Web VitalsINPNext.js
Читати статтю

Архітектура веб-продуктивності: системний аналіз 12 інженерних принципів (видання 2026)

Аспірантський розбір веб-продуктивності 2026 року: фізика мереж, інженерія конвеєра зображень, моделі виконання JavaScript, Critical Rendering Path, топологія edge-обчислень, діагностика Core Web Vitals та продакшн RUM - з бенчмарками та архітектурною глибиною.

EngineeringArchitectureCore Web Vitals
Читати статтю