Головна / Статті

Читання записів про продуктивність React у Chrome DevTools для виявлення повільного відображення

Дізнайтеся, як функції Scheduler, Components та Server у React 19.2 визначають, де витрачає час повільна взаємодія, та як працює процес record-fix-record для вирішення цієї проблеми.

Видавець: REACTAPP.TOP5 хв читання1081 слів

Джерела: Stop Guessing Why React Is Slow. Use the Performance Timeline.

Коли взаємодія з React здається повільною, першою реакцією є додавання useMemo, useCallback та React.memo у надії на покращення. Часто сторінка залишається повільною, тому що ніхто не вимірював, що саме споживає час. У React 19.2 були додані Performance Tracks, які записують активність React у часову шкалу продуктивності браузера; ось що показує кожен з цих записів та як перетворити запис на конкретне рішення проблеми.

Чому звичайна часова шкала була важкою для читання

Якщо записати повільну взаємодію у панелі Performance інструментів розробника Chrome для додатку без цих записів, основний потік зазвичай виглядає так:

JavaScript
████████████████████
██████████
███
████████████

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

Що додають трекери React

React надає спеціалізовані трекери для трьох сфер:

Scheduler
Components
Server

Вони розташовані поруч із звичайними потоками браузера, тож окремий слід можна прочитати приблизно так:

USER CLICK
    │
    ▼
┌─────────────────────────────┐
│ React Scheduler             │
│ Blocking → Render → Commit  │
├─────────────────────────────┤
│ React Components            │
│ Dashboard                   │
│ ├─ Header                   │
│ ├─ DataTable  ← expensive   │
│ └─ Chart                    │
├─────────────────────────────┤
│ Network / JavaScript        │
└─────────────────────────────┘

Цінність полягає у кореляції: активність React та активність браузера відображаються на одній спільній часовій осі.

Скедулятор: чому ця операція виконалась зараз?

React не обробляє кожне оновлення однаково. Механізм Scheduler розподіляє завдання за пріоритетом, використовуючи такі категорії, як Blocking, Transition, Suspense та Idle, і позначає етапи кожного оновлення: Update, Render, Commit та будь-які залишкові ефекти.

Це дозволяє відповісти на запитання на кшталт «чому є затримка під час введення тексту в це поле?». Трек може показати, що натискання клавіши запустило тяжкий синхронний процес відображення у категорії Blocking. Або ж може показати, що витратна операція вже була правильно обгорнута у процес переходу, що вказує на інше джерело проблеми. У будь-якому разі ви спираєтесь на докази, а не на інтуїцію. Якщо концепція переходів та пріоритетів нова для вас, модель, що лежить в основі цих категорій, описана у статті Understanding React Lanes.

Компоненти: хто виконав роботу?

Для щоденної дебаггінгу цей спосіб зазвичай є найкориснішим. Він відображає у форматі флеймграфа, скільки часу кожен компонент витратив на відображення та виконання ефектів, а під час розробки також дозволяє виділити змінені параметри та послідовні оновлення. Такий результат є типовим:

ProductPage        310ms
├── Header           12ms
├── Filters          18ms
├── DataTable       245ms  ←
└── Footer            8ms

Замість нечітких скарг на повільність React тепер у вас є точна інформація: DataTable зайняв більшу частину часу на відображення. Далі перевірте, чи він відображає занадто багато рядків, чи перераховує дані щоразу, чи отримує нові параметри від свого батьківського компонента щоразу.

Сервер: чи справді сторінка чекає на React?

У додатках, які використовують React Server Components, версії для розробки додатково відображають запити до сервера та роботу серверних компонентів у часовій шкалі. Це дозволяє виявити поширену хибну діагностику:

Slow page
   │
   ▼
Assume React render
   │
   X
   │
   ▼
Actually waiting on:
getProducts()
      │
      ▼
Database / API

Якщо трекінг показує, що сторінка «сидить без діла», поки getProducts() чекає на базу даних або API, виправлення має стосуватися процесу отримання даних — наприклад, кешування, паралельних запитів чи оптимізації запиту; використання React.memo для обгортки компонентів не допоможе. Саме тому потрібно бачити весь час виконання у одному перегляді.

Робочий процес дебаггінгу, який можна повторювати

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

1. Reproduce the problem
          ↓
2. Open Performance
          ↓
3. Record the interaction
          ↓
4. Find the slow React work
          ↓
5. Inspect the component / phase
          ↓
6. Check network and browser work
          ↓
7. Fix the actual bottleneck
          ↓
8. Record again

Не пропускайте останній крок. Знову записуйте дані за тих самих умов та порівнюйте. Оптимізація, яку ніколи не перевіряли знову, є лише гіпотезою; іноді другий трекінг показує, що зміни лише перемістили навантаження в інше місце, а не усунули його.

Знайте обмеження локального трекінгу

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

Це означає, що наявність чистих записів діяльності програми на вашому пристрої не гарантує швидкої роботи для справжніх користувачів. Для оцінки продуктивності у продакшені все одно потрібні дані з реальних умов та моніторинг діяльності користувачів. Трекери відповідають на більш вузьке, але дуже практичне запитання: що саме робить додаток, крок за кроком, під час виникнення цієї конкретної проблеми?

Основні висновки

Найбільш шкідливою звичкою щодо продуктивності є не вибір неправильного інструменту; це оптимізація до того, як зрозуміти проблему. Більш розсудливий підхід виглядає так:

Slow interaction
       │
       ▼
    Measure
       │
       ▼
 Find the bottleneck
       │
 ┌─────┼──────┐
 ▼     ▼      ▼
React Network Browser
 │      │      │
 ▼      ▼      ▼
Fix    Fix    Fix
  • Спочатку вимірюйте: саме треки роблять запис та визначення «вузького місця» простими завданнями.
  • Використовуйте трек Scheduler, щоб зрозуміти пріоритет та етап виконання, а трек Components — щоб знайти дорогий піддрівень.
  • Перевіряйте трек Server та мережеві канали, перш ніж припускати, що проблема у процесі відтворення.
  • Знову записуйте після кожної зміни, щоб підтвердити ефективність виправлення.
  • Розглядайте локальні записи як засіб діагностики, а для оцінки того, що відчувають користувачі, покладайтеся на дані з поля.

У такому форматі фокус розмови зміщується від питання про необхідність додавання useMemo до того, що насправді спожило ці 200 мілісекунд, і саме це питання допомагає знайти справжнє рішення.