React Server Components: впровадження для продуктивності

React Server Components: впровадження для продуктивності

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
React Server Components: впровадження для продуктивності
Складний
~5 днів

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

React Server Components: впровадження для продуктивності

Типова ситуація: сторінка каталогу в Next.js App Router завантажує 200 КБ JS на клієнт, хоча 80% коду — статичний вивід товарів. Ви використовуєте getServerSideProps, API routes і весь UI обгортаєте в 'use client'. Як результат — повільне завантаження на мобільних та низький LCP. Рішення — Next.js з React Server Components (RSC): компоненти, які виконуються тільки на сервері і не надсилають жодного байта JS у браузер. React documentation states: "Server Components render on the server and send zero JavaScript to the client." Це змінює підхід до архітектури: ви можете напряму звертатися до БД з компонента, не створюючи окремий API-шар. Ми допомагаємо впровадити RSC у ваш проєкт — від аудиту до повної міграції.

Чому RSC — не просто покращення SSR?

SSR рендерить React-компоненти на сервері та надсилає HTML, але все одно вимагає завантаження та гідратації JS на клієнті. RSC — окремий тип компонентів, які ніколи не гідратуються та не додають JS у бандл. Порівняння:

Характеристика SSR (getServerSideProps) RSC (App Router)
HTML на сервері Так Так
Гідратація JS Повна гідратація Тільки клієнтські компоненти
Розмір JS-бандла Весь компонент Тільки інтерактивні частини
Запити до БД Через API (окремий шар) Прямі імпорти в компоненті
Стан на клієнті useState / Redux Там, де потрібно

Типові помилки при розмежуванні: часто весь UI-компонент позначають 'use client' через один обробник. Правильніше винести інтерактивну частину в окремий клієнтський компонент, а решту залишити серверним. Не можна використовувати серверні компоненти в провайдерах контексту — вони мають бути клієнтськими.

Як розмежувати Server Components і Client Components?

Приклад: серверний компонент, який отримує товари з БД і рендерить список, а клієнтський — тільки кнопка додавання в кошик.

// СЕРВЕРНИЙ компонент (за замовчуванням в App Router) // Цей код НІКОЛИ не потрапляє в браузер import { db } from '@/lib/db'; // Прямий імпорт Prisma/Drizzle — нормально import { unstable_cache } from 'next/cache'; const getProducts = unstable_cache( async (categoryId: string) => { return db.product.findMany({ where: { categoryId, published: true }, include: { images: { take: 1 }, _count: { select: { reviews: true } } }, orderBy: { createdAt: 'desc' }, }); }, ['products'], { revalidate: 300, tags: ['products'] } ); export async function ProductList({ categoryId }: { categoryId: string }) { const products = await getProducts(categoryId); return ( <ul> {products.map(product => ( <li key={product.id}> <ProductCard product={product} /> <AddToCartButton productId={product.id} /> </li> ))} </ul> ); } 
// КЛІЄНТСЬКИЙ компонент — 'use client' обов'язковий 'use client'; import { useState, useTransition } from 'react'; import { addToCart } from '@/actions/cart'; // Server Action export function AddToCartButton({ productId }: { productId: string }) { const [isPending, startTransition] = useTransition(); return ( <button onClick={() => startTransition(() => addToCart(productId))} disabled={isPending} > {isPending ? 'Додаємо...' : 'В кошик'} </button> ); } 

Що можуть і чого не можуть Server Components

Server Components можуть: async/await на верхньому рівні, прямі запити до БД без API, читання змінних оточення, імпорт server-only бібліотек, рендеринг інших серверних та клієнтських компонентів. Не можуть: використовувати useState, useEffect, useContext, обробляти браузерні події, використовувати браузерні API, приймати функції як пропси.

Server Actions — мутації без API

// app/actions/products.ts 'use server'; import { revalidateTag } from 'next/cache'; import { redirect } from 'next/navigation'; import { db } from '@/lib/db'; import { auth } from '@/lib/auth'; import { z } from 'zod'; const UpdateProductSchema = z.object({ name: z.string().min(1).max(255), price: z.number().positive(), description: z.string().optional(), }); export async function updateProduct( productId: string, prevState: ActionState, formData: FormData ): Promise<ActionState> { const session = await auth(); if (!session?.user) return { error: 'Unauthorized' }; const parsed = UpdateProductSchema.safeParse({ name: formData.get('name'), price: Number(formData.get('price')), description: formData.get('description'), }); if (!parsed.success) { return { error: parsed.error.flatten().fieldErrors }; } await db.product.update({ where: { id: productId }, data: parsed.data, }); revalidateTag('products'); redirect(`/products/${productId}`); } 
// Використання у формі через useActionState 'use client'; import { useActionState } from 'react'; import { updateProduct } from '@/actions/products'; export function EditProductForm({ product }: { product: Product }) { const [state, action, isPending] = useActionState( updateProduct.bind(null, product.id), null ); return ( <form action={action}> <input name="name" defaultValue={product.name} required /> {state?.error?.name && <p>{state.error.name[0]}</p>} <input name="price" type="number" defaultValue={product.price} /> <button type="submit" disabled={isPending}> {isPending ? 'Збереження...' : 'Зберегти'} </button> </form> ); } 

Оптимізація: context та провайдери

Поширена помилка — обгортати весь додаток у Client Component з провайдером:

// Погано: весь layout стає клієнтським 'use client'; export function Layout({ children }) { return <ThemeProvider><AuthProvider>{children}</AuthProvider></ThemeProvider>; } // Добре: провайдери ізольовані, children — серверні // providers.tsx 'use client'; export function Providers({ children }: { children: React.ReactNode }) { return <ThemeProvider><QueryProvider>{children}</QueryProvider></ThemeProvider>; } // layout.tsx — серверний import { Providers } from './providers'; export default async function RootLayout({ children }) { const session = await auth(); // Серверний запит у layout return ( <html> <body> <Providers session={session}>{children}</Providers> </body> </html> ); } 

Як впровадження RSC впливає на розмір JS-бандла?

Типовий результат міграції продуктових сторінок на RSC:

Компонент До RSC Після RSC
ProductList (дані + рендер) 24 KB JS 0 KB JS
ProductDetails 8 KB JS 0 KB JS
AddToCartButton 2 KB JS 2 KB JS (клієнтський)
Разом на сторінці 180 KB 85 KB

Серверні компоненти не додають JS — вони додають тільки HTML у потік відповіді. Це дає виграш у 2-3 рази за розміром бандла та покращує показники Core Web Vitals (LCP, TTFB). Економія на CDN-трафіку може досягати $2,000 на місяць для середнього інтернет-магазину. Середній проєкт окупається за 4-6 місяців.

Що входить у роботу

Ми пропонуємо комплексне впровадження RSC у ваш проєкт:

  • Аудит поточної архітектури: виявлення компонентів, які можна зробити серверними. Розмітка server/client меж: визначення, які компоненти залишаться на клієнті.
  • Перенесення data-fetching з API routes у серверні компоненти з прямим доступом до БД. Налаштування Server Actions для мутацій (форми, кошик, улюблене).
  • Оптимізація провайдерів: винесення клієнтського коду в ізольовані компоненти, збереження серверного layout. Кешування через unstable_cache та revalidateTag для керування свіжістю даних.
  • Вимірювання JS-бандла до та після, моніторинг серверного рендера. Документація меж та навчання команди (воркшоп по RSC).

Чому обирають нас

Ми — команда з досвідом у Next.js та React. За цей час реалізували десятки проєктів з впровадження RSC для e-commerce, медіа та SaaS. Наші інженери сертифіковані та регулярно виступають на конференціях. Ми гарантуємо результат: зниження JS-бандла на 50–70% та покращення LCP на 40% порівняно з CSSR-підходом.

Терміни реалізації

  • Тиждень 1–2: аудит існуючих компонентів, розмітка server/client меж, перенесення data-fetching з API routes у серверні компоненти.
  • Тиждень 3: Server Actions для форм та мутацій, заміна REST-викликів на прямі DB-запити.
  • Тиждень 4: оптимізація провайдерів (винесення на клієнт без забруднення layout), кешування через unstable_cache.
  • Тиждень 5: вимірювання JS bundle до/після, тести, документація меж.
  • Тиждень 6: деплой, моніторинг серверного рендера, навчання команди.

Замовте безкоштовний аудит свого проєкту — ми допоможемо оцінити потенціал впровадження RSC та скласти план міграції. Отримайте консультацію інженера з оптимізації продуктивності.