·3 хв читання·fluxLab.dev

Патерни продуктивності React, які ми використовуємо на продакшні

Практичні патерни продуктивності React із продуктів fluxLab.dev: code splitting, мемоізація, віртуалізація та оптимізація зображень.

ReactПродуктивністьNext.jsFrontend

Вступ

Продуктивність у fluxLab.dev — це не запізніла думка, а фіча. У наших продуктах ми виробили патерни, що тримають React-додатки швидкими навіть при зростанні складності. Це техніки, які дали найбільший ефект.

Патерн 1: Server Components за замовчуванням

У Next.js App Router кожен компонент — Server Component, поки ви не додасте 'use client'. Ми використовуємо це максимально агресивно.

Правило

Додавайте 'use client' лише коли вам потрібні:

  • Обробники подій (onClick, onChange)
  • Browser API (localStorage, window)
  • React-хуки (useState, useEffect)

У фронтенді Jobber 70% компонентів — Server Components. Вони додають нуль JavaScript у клієнтський бандл.

Патерн 2: Lazy load нижче фолду

Все, що не видно при початковому завантаженні сторінки, завантажується лінійно:

import dynamic from 'next/dynamic';

const Analytics = dynamic(() => import('./analytics'), {
  loading: () => <AnalyticsSkeleton />,
});

Для аналітичної панелі Jobber lazy loading компонентів графіків зменшив початковий бандл на 120КБ. Користувачі бачать макет сторінки миттєво, а графіки завантажуються під час скролу.

Патерн 3: Оптимізація зображень з Next/Image

Кожне зображення в наших продуктах використовує next/image з правильною конфігурацією:

<Image
  src={screenshot.src}
  alt={screenshot.alt}
  fill
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 80vw, 1100px"
/>

Атрибут sizes критично важливий — він повідомляє браузеру, який розмір зображення завантажити залежно від ширини viewport. Без нього браузер щоразу завантажує найбільше зображення.

Патерн 4: Дебаунс інпутів пошуку та фільтрів

Пошук у реальному часі коштує дорого. Ми дебаунсимо всі пошукові інпути на 300мс:

function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debouncedValue;
}

У списку компаній Jobber це зменшило кількість API-викликів на 80%, зберігаючи відгукливість інтерфейсу.

Патерн 5: Віртуалізація довгих списків

Для списків з понад 50 елементами ми використовуємо віртуалізацію. У DOM рендеряться лише видимі елементи. Kanban-дошка в Jobber використовує цей патерн — навіть із сотнями карток заявок скрол залишається плавним, бо в DOM одночасно перебуває лише 10-15 карток.

Патерн 6: Оптимістичні оновлення для Drag-and-Drop

Коли користувач перетягує картку заявки між колонками на Kanban-дошці Jobber, ми оновлюємо UI миттєво — ще до завершення виклику API. Якщо виклик API завершується невдало, ми відкатуємо зміну і показуємо помилку.

Це робить drag-and-drop миттєвим на відчуття, навіть попри те, що оновлення на бекенді триває 50-100мс.

Патерн 7: Попереднє завантаження критичних даних

Для сторінок, які користувач, ймовірно, відвідає далі, ми завантажуємо дані заздалегідь при наведенні курсору:

<Link
  href={`/projects/${slug}`}
  onMouseEnter={() => prefetchProject(slug)}
>

Це знімає 200-400мс із сприйманого часу навігації, бо дані вже закешовані в момент кліку користувача.

Патерн 8: Аналіз бандлу

Ми запускаємо @next/bundle-analyzer на кожному релізі, щоб відловлювати регресії розміру бандлу. Будь-яке зростання понад 10КБ потребує обґрунтування.

Типові знахідки:

  • Імпорт цілої бібліотеки іконок замість окремих іконок
  • Бібліотеки дат (moment.js → date-fns → нативний Intl)
  • Невикористаний CSS з бібліотек компонентів

Вимірювання продуктивності

Ми відстежуємо Core Web Vitals у продакшні:

  • LCP (Largest Contentful Paint): ціль менше 2.5с
  • INP (Interaction to Next Paint): ціль менше 200мс
  • CLS (Cumulative Layout Shift): ціль менше 0.1

Наш портфоліо-сайт (flux-lab.dev) набирає 95+ балів у Lighthouse за всіма метриками.

Висновок

Оптимізація продуктивності React — це послідовний вибір розумних рішень: Server Components замість Client Components, lazy loading замість жадібного завантаження та вимірювання перед оптимізацією. Ці патерни тримають наші продукти швидкими в усіх наших продакшн-розгортаннях.

Якщо ваш React-застосунок здається повільним і ви не знаєте чому, ми можемо допомогти. Кожна співпраця починається з вимірювання.

Читайте також

·8 хв читання

Як ми будуємо продакшн веб-додатки на Next.js

Як влаштований наш сайт на Next.js 16: Server Components, маршрути з префіксами локалей, hreflang на кожній сторінці, форми з Zod, Tailwind 4 і Docker.

Next.jsReactTypeScript
Читати Далі
·4 хв читання

Уроки продуктивності PostgreSQL з досвіду 6 SaaS-продуктів

Уроки оптимізації PostgreSQL з експлуатації продакшн SaaS-баз даних у fluxLab.dev: індексація, тюнінг запитів, N+1 запити та пулінг з'єднань.

PostgreSQLПродуктивністьБази данихSaaS
Читати Далі