Читання записів про продуктивність React у Chrome DevTools для виявлення повільного відображення
Дізнайтеся, як функції Scheduler, Components та Server у React 19.2 визначають, де витрачає час повільна взаємодія, та як працює процес record-fix-record для вирішення цієї проблеми.
Джерела: 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 мілісекунд, і саме це питання допомагає знайти справжнє рішення.