React Server Components: внедрение для производительности

Страницы загружаются медленно из-за тяжёлого JS-бандла, который уходит клиенту даже для статичного контента. Мы внедряем React Server Components в ваш проект на Next.js, чтобы сервер отдавал готовый HTML без лишнего кода в браузере. Наша команда проведёт аудит, разграничит серверные и клиентские компоненты и реализует миграцию под ключ — с последующей поддержкой и оптимизацией производительности.

Разработка и обслуживание любых видов сайтов:

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

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

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

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 и составить план миграции. Получите консультацию инженера по оптимизации производительности.

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

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060