Performanță în React
De ce se re-randează o componentă, memo, useMemo, useCallback, useTransition, virtualizare.
Actualizat
Ce înseamnă performanță în React
O aplicație React e lentă de obicei din două motive: re-randează prea mult (componente care nu s-au schimbat sunt recalculate) sau face prea multă muncă într-o randare (o listă de 5.000 de rânduri, un calcul greu). Înainte de orice optimizare, măsori — cu React DevTools → Profiler.
Când se re-randează o componentă
- State-ul ei s-a schimbat.
- Părintele s-a re-randat (implicit, toți copiii se re-randează — chiar dacă props-urile sunt identice).
- Un Context pe care îl citește și-a schimbat valoarea.
O re-randare nu înseamnă modificare de DOM — React compară rezultatul și atinge DOM-ul doar unde e diferență. Re-randările sunt de obicei ieftine; devin problemă la componente mari sau foarte dese.
Uneltele — ce face fiecare
| Unealtă | Ce face | Când |
|---|---|---|
| mutarea state-ului mai jos | doar componenta mică se re-randează | prima opțiune, gratuită |
children ca prop |
conținutul pasat nu se re-randează cu părintele | wrapper-e cu state (modal, accordion) |
memo(Component) |
sare peste re-randare dacă props-urile sunt egale (Object.is) |
componentă scumpă, re-randată des cu aceleași props |
useMemo(() => calc, deps) |
păstrează rezultatul unui calcul | calcul greu sau obiect pasat unui memo |
useCallback(fn, deps) |
păstrează aceeași funcție între randări | funcție pasată unui memo sau folosită în deps |
useTransition / useDeferredValue |
marchează o actualizare ca ne-urgentă | filtrare de listă mare la tastare — input-ul rămâne fluid |
| virtualizare | randează doar rândurile vizibile | liste de mii de elemente (TanStack Virtual) |
React Compiler
React Compiler analizează codul la build și adaugă automat memoizarea (echivalentul memo / useMemo / useCallback) unde e nevoie. Cu el activat, scrii cod simplu, iar majoritatea memoizărilor manuale devin inutile. Next.js îl suportă prin opțiunea reactCompiler din next.config.ts.
Condiția: codul respectă regulile React — componente pure, fără mutarea props-urilor sau a state-ului.
Capcana referințelor
const Row = memo(function Row({ item, onSelect }) { ... })
function List({ items }) {
return items.map(item => (
<Row key={item.id} item={item} onSelect={() => select(item.id)} /> // funcție NOUĂ la fiecare randare
))
}memo compară props-urile prin referință; o funcție sau un obiect creat inline e mereu „nou” → memo nu ajută. De aici useCallback / useMemo — sau React Compiler.
Ordinea în care optimizezi
- Măsoară (Profiler): ce componentă, cât durează, de ce se re-randează.
- Mută state-ul mai aproape de unde e folosit; separă componentele.
- Server Components pentru tot ce nu e interactiv — zero cost pe client.
- Virtualizare pentru liste lungi;
useTransitionpentru actualizări grele. memo/useMemo/useCallbackțintit — sau activezi React Compiler.
Pe scurt
- Re-randare = state propriu, părinte re-randat sau Context schimbat; măsori cu Profiler.
- Întâi structura (state mai jos,
children), apoimemo+useMemo/useCallback. useTransitionpentru actualizări grele, virtualizare pentru liste mari, React Compiler pentru memoizare automată.