Анотація. 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 - послуга архітектури фронтенду | кейси | обговорити задачу.
Джерела
- Abramov, D. et al. React RFC #188 (грудень 2020): https://github.com/reactjs/rfcs/pull/188
- React Team. React 19 Release Notes: https://react.dev/blog/2024/12/05/react-19
- React Team. RSC Documentation: https://react.dev/reference/rsc/server-components
- Next.js Team. App Router Docs: https://nextjs.org/docs/app
- Next.js Team. Partial Prerendering: https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering
- Vercel. 'Partial Prerendering' (2025): https://vercel.com/blog/partial-prerendering
- Shopify Engineering. 'Hydrogen 2 RSC Benchmarks' (жовтень 2024): https://shopify.engineering
- HTTP Archive 2025 Web Almanac: https://almanac.httparchive.org
- React Conf 2024, React Compiler: https://conf.react.dev
- Osmani, A. 'Patterns for Building React Applications' (2025): https://patterns.dev
