Strona główna / Artykuły

Czytanie ścieżek wydajności React w Chrome DevTools w celu znalezienia wolnych procesów renderowania

Dowiedz się, w jaki sposób Scheduler, Components i Server dodane w React 19.2 pokazują, gdzie traci czas wolna interakcja, oraz jak wykorzystać proces record-fix-record do podjęcia działań w tej sprawie.

Wydawca: REACTAPP.TOP5 min czytania1081 słów

Źródła: Stop Guessing Why React Is Slow. Use the Performance Timeline.

Gdy interakcja w React wydaje się powolna, pierwszą reakcją jest dodanie useMemo, useCallback i React.memo oraz mieć nadzieję. Często strona pozostaje wolna, ponieważ nikt nie zmierzył, co pochłania czas. W React 19.2 dodano Performance Tracks, które zapisują aktywność React w chronologii wydajności przeglądarki; oto, co pokazuje każda z tych ścieżek oraz jak przekształcić nagranie w skuteczną poprawkę.

Dlaczego zwykła chronologia była trudna do odczytania

Nagryj powolną interakcję w panelu Performance narzędzi deweloperskich Chrome w aplikacji bez tych ścieżek – główny wątek zazwyczaj wygląda w ten sposób:

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

JavaScript jest wyraźnie zajęty, ale który komponent był za to odpowiedzialny, która aktualizacja rozpoczęła renderowanie, czy strona czekała na dane z sieci, czy jakiś efekt dominował nad procesem, oraz czy React wykonał renderowanie dokładnie w momencie, gdy użytkownik oczekiwał natychmiastowej odpowiedzi? Ogólny przegląd nie pozwala to ustalić na podstawie nazw funkcji – React Track dostarcza brakującego kontekstu.

Czym są React Tracki

React dostarcza specjalne tracki dla trzech obszarów:

Scheduler
Components
Server

Znajdują się one obok standardowych ścieżek przeglądarki, więc pojedynczy zapis można odczytać mniej więcej w ten sposób:

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

Wartość leży w korelacji: aktywność Reacta i aktywność przeglądarki są pokazywane na jednej wspólnej osi czasu.

Scheduler: dlaczego ten proces został uruchomiony teraz?

React nie obsługuje każdej aktualizacji w ten sam sposób. Scheduler dzieli zadania według priorytetu, wykorzystując takie kategorie jak Blocking, Transition, Suspense i Idle, oraz oznacza fazy każdej aktualizacji: Update, Render, Commit oraz wszelkie pozostałe efekty.

Dzięki temu można odpowiedzieć na pytania takie jak „dlaczego wpisywanie tekstu w to pole jest wolne?”. Ślad działania może pokazać, że naciśnięcie klawisza uruchomiło intensywną, synchroniczną renderizację w kategorii Blocking. Albo może pokazać, że kosztowne zadanie zostało już prawidłowo umieszczone w fazie transition, co skieruje uwagę w inne miejsce. W obu przypadkach pracujesz na podstawie dowodów, a nie intuicji. Jeśli transycje i priorytety są dla ciebie nowością, model stojący za tymi kategoriami jest omówiony w artykule Understanding React Lanes.

Komponenty: kto wykonał pracę?

Dla codziennego debugowania to zazwyczaj najprzydatniejsza metoda. W formie flamegrapha pokazuje, ile czasu poświęcił każdy komponent na renderowanie i wykonywanie efektów, a w fazie rozwoju może również podkreślić zmienione właściwości oraz łańcuchowe aktualizacje. Taki wynik jest typowy:

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

Zamiast niejasnych skarg na wolność Reacta, masz teraz precyzyjny wskazówkę: DataTable pochłonął większość czasu na renderowanie. Następnie sprawdź, czy renderuje zbyt wiele wierszy, ponownie oblicza dane przy każdym przetworzeniu lub otrzymuje nowe właściwości od swojego rodzica za każdym razem.

Serwer: czy strona w ogóle czeka na Reacta?

W aplikacjach wykorzystujących React Server Components, wersje rozwojowe dodatkowo pokazują żądania serwera oraz pracę komponentów serwerowych na osi czasu. To ujawnia częsty błędny diagnoz:

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

Jeśli śledzenie pokazuje, że strona jest bezczynna, podczas gdy getProducts() czeka na bazę danych lub API, rozwiązanie leży w procesie pobierania danych – np. poprzez cacheowanie, żądania równoległe lub bardziej efektywne zapytania – a umieszczanie komponentów w React.memo nie pomoże. Właśnie dlatego chce się mieć cały harmonogram wykonywania w jednym widoku.

Powtarzalny proces debugowania

Gdy interakcja wydaje się powolna, za każdym razem postępuj zgodnie z tą samą sekwencją:

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

Nie pomijaj ostatniego kroku. Zrób ponowne nagranie w tych samych warunkach i porównaj wyniki. Optymalizacja, której efektów nigdy ponownie nie zmierzono, jest jedynie hipotezą; czasami drugie nagranie pokazuje, że zmiana przeniosła koszt w inne miejsce zamiast go usunąć.

Znajomość ograniczeń lokalnego śledzenia

Ślady wydajności są narzędziem pomocniczym przy rozwoju i profilowaniu. React informuje, że takie narzędzia dodają obciążenia i są domyślnie wyłączane w wersjach produkcyjnych, natomiast ślady serwerowe dotyczą wyłącznie wersji rozwojowych. Wersje rozwojowe działają również wolniej, dlatego należy bardziej ufać proporcjom niż wartościom bezwzględnym.

To oznacza, że czysty ślad na twoim komputerze nie dowodzi, iż rzeczywiści użytkownicy mają szybką obsługę. W przypadku wydajności w środowisku produkcyjnym nadal konieczne są dane z terenu i monitorowanie rzeczywistych użytkowników. Ślady odpowiadają na węższe, ale bardzo praktyczne pytanie: co aplikacja robi krok po kroku, gdy próbujesz odtworzyć ten konkretny problem?

Główne wnioski

Najdroższym nawykiem wpływającym na wydajność nie jest wybór niewłaściwego narzędzia; jest to optymalizacja przed zrozumieniem problemu. Solidniejsze podejście wygląda następująco:

Slow interaction
       │
       ▼
    Measure
       │
       ▼
 Find the bottleneck
       │
 ┌─────┼──────┐
 ▼     ▼      ▼
React Network Browser
 │      │      │
 ▼      ▼      ▼
Fix    Fix    Fix
  • Najpierw zmierz: ślady ułatwiają nagrywanie i lokalizację wąskiego gardła.
  • Użyj śladu Scheduler, aby zrozumieć priorytet i fazę, a śladu Components, by znaleźć kosztowny poddrzewo.
  • Zbadaj ślad Server oraz kanały sieciowe, zanim założysz, że problem leży w procesie renderowania.
  • Nagraj ponownie po każdej zmianie, aby potwierdzić poprawę.
  • Rozpatruj lokalne ślady jako narzędzie diagnostyczne, a dane z pola testów jako odzwierciedlenie doświadczeń użytkowników.

W ten sposób rozmowa przechodzi od pytania, czy dodać useMemo, do ustalenia tego, co faktycznie pochłonęło te 200 milisekund – to właśnie to pytanie prowadzi do rzeczywistej poprawy.

Literatura pokrewna

  • Adopcja React 19.2: Aktywność dla interfejsów z kartkami i lista weryfikacyjna aktualizacji — Jak mechanizm Activity w React 19.2 utrzymuje ukryte karty aktywne, gdzie znajdują zastosowanie funkcje useEffectEvent i pre-rendering oraz jak zdecydować, czy należy już teraz aktualizować aplikacje RSC i naprawiać ich błędy.