Osiągi React poza ręcznym użyciem memo: struktura i planowanie
Rada z czasów kompilatorów: umieszczaj stan w jednym miejscu, oddziel pracę pilną, wysyłaj mniej kodu JS, a następnie memoizuj identyfikowane punkty o najwyższym obciążeniu.
Przez lata zalecenia dotyczące wydajności w React polegały na otaczaniu wszystkiego funkcjami memo:
const value = useMemo(() => expensiveCalculation(data), [data]);
const handleClick = useCallback(() => {
doSomething(id);
}, [id]);export default React.memo(Component);
function ProductList({ products, onSelect }) {
const processed = useMemo(
() => processProducts(products),
[products]
);
const handleSelect = useCallback(
(id) => onSelect(id),
[onSelect]
); return (
<List
products={processed}
onSelect={handleSelect}
/>
);
}
App
│
├── Header
├── Sidebar
├── Search
├── ProductList
└── Footer
function App() {
const [query, setQuery] = useState("");
// large component tree
}
App
│
├── Header
├── Sidebar
├── Search
│ └── query state
├── ProductList
└── Footer
const [query, setQuery] = useState("");
const [isPending, startTransition] = useTransition();
function handleChange(event) {
const value = event.target.value; setQuery(value); startTransition(() => {
setSearchResults(filterProducts(value));
});
}
User input
│
├── urgent ───────► keep UI responsive
│
└── non-urgent ───► transition
const AnalyticsDashboard = lazy(
() => import("./AnalyticsDashboard")
);
Initial JavaScript
│
▼
┌─────────────────────┐
│ Everything │
│ Dashboard │
│ Analytics │
│ Editor │
│ Admin │
└─────────────────────┘
Initial load
│
├── Core UI
│
└── Later
├── Analytics
├── Editor
└── Admin
"This component renders often."
│
▼
Add useMemo
"This component renders often."
│
▼
Why?
│
┌──────┼───────────┐
▼ ▼ ▼
State Expensive Large
flow work subtree
│ │ │
▼ ▼ ▼
Colocate Optimize Restructure
1. Measure
↓
2. Find the expensive work
↓
3. Fix component architecture
↓
4. Reduce unnecessary JavaScript
↓
5. Prioritize updates correctly
↓
6. Let React Compiler handle memoization
↓
7. Manually optimize only when evidence says you should
Samo memoizowanie nie naprawia wolnych aplikacji. Doskonale zmemorizowana struktura może nadal mieć problemy z powodu zbyt dużych stanów, pilnych aktualizacji wykonywających niepilne zadania lub obciążonego JavaScriptu na głównej wątku.
React Compiler zmienia standard
Kompilator automatyzuje wiele zasobów do memoizacji. Dzięki temu wysiłek ludzki skupia się na strukturze i planowaniu — a nie na ręcznym umieszczaniu funkcji useMemo we wszystkich miejscach.
Najpierw: umieść stan bliżej miejsca, gdzie jest używany
Wysoki poziom stanu w drzewie powoduje ponowne renderowanie rozległych poddrzew. Umieszczaj stan razem z liśćmi, które go potrzebują; aktualizuj go tylko wtedy, gdy wymaga tego współdzielenie.
Po drugie: nie zmuszaj pilnych aktualizacji do wykonywania prac nieważnych
Zapewnij, aby pisanie i animacje pozostawały responsywne. Odkładaj prace nieważne za pomocą przejść lub wartości odroczonych, aby klawisze nie były blokowane kosztownymi filtrami.
Po trzecie: przyjrzyj się JavaScriptowi, który wysyłasz
Zanim to zrobi komparator React, dominują duże pętle synchronizacyjne, kosztowne formatery oraz nieograniczone listy. Przeprowadź profilowanie kodu JS, a nie tylko korzystaj z wskazówek narzędzi React DevTools.
Kiedy więc należy używać useMemo?
Nadal przydatne jest ono dla zachowania stabilności referencyjnej wśród dzieci, które rezygnują z propów, oraz przy naprawdę kosztownych, czystych obliczeniach — po ich zmierzeniu. Nie jako standardowe rozwiązanie dla każdej wartości.
Nowe podejście do wydajności w React
Struktura → planowanie → mniej kodu JS do wysyłki → następnie mikro-memoizacja najczęściej używanych elementów. Memoizacja wspomagana przez kompilator jest narzędziem pomocniczym, a nie zamiennikiem dobrego projektowania.
Należy dodać budżet wydajności do propozycji zmian: czas reakcji na następne odświeżenie interfejsu dla głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanych, obciążających ścieżek.
Listy powinny zostać zvirtualizowane, zanim zaczną memoizować każdy wiersz. Memoizacja przy 10 tysiącach wierszy nadal przynosi gorsze wyniki.
Należy dodać budżet wydajności do propozycji zmian: czas reakcji na następne odświeżenie interfejsu dla głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanych, obciążających ścieżek.
Listy powinny zostać zvirtualizowane, zanim zaczną memoizować każdy wiersz. Memoizacja przy 10 tysiącach wierszy nadal przynosi gorsze wyniki.
Należy dodać budżet wydajności do propozycji zmian: czas reakcji na następne odświeżenie interfejsu dla głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanych, obciążających ścieżek.
Listy powinny zostać zvirtualizowane, zanim zaczną memoizować każdy wiersz. Memoizacja przy 10 tysiącach wierszy nadal przynosi gorsze wyniki.
Dodaj budżet wydajności do PR-ów: czas potrzebny na przemalowanie głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanej, obciążonej trasy.
Listy powinny zostać zvirtualizowane, zanim zapamiętają każdy wiersz. Użycie mechanizmu memoization przy 10 tysiącach wierszy nadal skutkuje stratami wydajności.
Dodaj budżet wydajności do PR-ów: czas potrzebny na przemalowanie głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanej, obciążonej trasy.
Listy powinny zostać zvirtualizowane, zanim zapamiętają każdy wiersz. Użycie mechanizmu memoization przy 10 tysiącach wierszy nadal skutkuje stratami wydajności.
Dodaj budżet wydajności do PR-ów: czas potrzebny na przemalowanie głównego formularza oraz zrzut ekranu z narzędzia do analizy wydajności React dla znanej, obciążonej trasy.
Listy powinny zostać zvirtualizowane, zanim zapamiętają każdy wiersz. Użycie mechanizmu memoization przy 10 tysiącach wierszy nadal skutkuje stratami wydajności.
Literatura pokrewna
- Dlaczego React.memo nadal przerysowuje: identyfikator odniesienia w propach — Dowiedz się, jak React.memo porównuje propy, dlaczego funkcje wewnątrz linii, obiekty i tablice go obezwładniają, jak ustabilizować odniesienia oraz dlaczego profilowanie powinno poprzedzać tworzenie memo.
- React 19.3 poza hasełkami: submitter, propy Fullscreen i rozmiar bundlu — Praktyczny przegląd mniejszych zmian w React 19.3: właściwość submitter, propy zdarzenia Fullscreen, równoległe przejścia, funkcja onReset, istotne poprawki błędów oraz rzeczywisty wzrost rozmiaru.