eduardweb.
React Native & ExpoIntermediar#performance#react-native#mobile#javascript

React Native Performance: Când merită memo, useCallback și FlashList

De Paul Ene, 8 aug. 2026 · 8 vizualizări · 2 like-uri

Postat 8 aug. 2026
typescript
import React, { memo, useCallback } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { FlashList } from '@shopify/flash-list';

type ItemProps = { id: string; title: string; onSelect: (id: string) => void };

// 1. React.memo oprește re-renderarea dacă props-urile sunt identice
const ListItem = memo(({ id, title, onSelect }: ItemProps) => {
  return (
    <TouchableOpacity onPress={() => onSelect(id)} style={{ padding: 16 }}>
      <Text>{title}</Text>
    </TouchableOpacity>
  );
});

export const ProductList = ({ data }: { data: Array<{ id: string; title: string }> }) => {
  // 2. useCallback păstrează referința stabilă pentru ListItem-ul memoizat
  const handleSelect = useCallback((id: string) => {
    console.log('Selected product:', id);
  }, []);

  return (
    <FlashList
      data={data}
      renderItem={({ item }) => (
        <ListItem id={item.id} title={item.title} onSelect={handleSelect} />
      )}
      estimatedItemSize={70}
      keyExtractor={(item) => item.id}
    />
  );
};

Salutare! Am văzut din ce în ce mai des PR-uri unde fiecare funcție e îmbrăcată automat în useCallback și orice obiect trece prin useMemo. Să fim sinceri: în 80% din cazuri doar adaugi overhead de memorie și îngreunezi citirea codului.

Anul trecut lucram la un e-commerce local cu peste 15k produse în catalog. În ecranele de listă, thread-ul de JS agăța masiv la scroll – aveam drop-uri de la 60 FPS la 20-22 FPS pe dispozitive mid-range de Android. Prima reacție a echipei a fost: "hai să punem useCallback pe toate handlerele de onPress". Rezultatul? Nicio diferență sesizabilă.

useCallback nu face o funcție mai rapidă. El doar păstrează aceeași referință în memorie între re-renderări. Dacă componenta copil care primește acea funcție NU este învelită în React.memo, copilul se va re-rendera ORICUM pentru că părintele s-a re-renderat. Ai plătit prețul de hook degeaba.

Când chiar folosești memo, useCallback și useMemo

Iată regula mea simplă după mai bine de 10 ani de dev:

  1. React.memo: Îl pui pe componente vizuale grele sau pe elemente de listă care se repetă de sute de ori (ex: ProductCard). Dacă o componentă e simplă (un Text și un Icon), costul diferențierii props-urilor făcut de memo poate fi mai mare decât re-renderarea ei nativă.
  2. useCallback: Îl folosești EXCLUSIV când pasezi callback-ul către o componentă copil optimizată deja cu React.memo sau când funcția este o dependență într-un useEffect.
  3. useMemo: Util pentru calcule grele (filtrări, sortări pe array-uri de mii de obiecte). Dacă doar faci un .map() simplu pe 10 elemente, useMemo e inutil.

La proiectul menționat, aveam carduri complexe de produs. Doar când am pus React.memo pe ProductCard ȘI useCallback pe funcția de onAddToCart, re-renderările inutile la scroll au scăzut cu aproape 70%.

FlatList vs FlashList: De la 22 la 60 FPS

Toată lumea știe că FlatList din React Native folosește VirtualizedList. Problema e că FlatList nu reciclează componentele native, ci le distruge și le recreează la scroll rapid. Pe un Android ieftin, asta înseamnă spații albe și vizibil lag.

Am migrat lista principală către @shopify/flash-list. Pentru că FlashList reciclează views-urile native exact ca un RecyclerView pe Android sau UICollectionView pe iOS, timpul de render pe JS thread a scăzut dramatic. Am economisit cam 30% memorie RAM și am scos FPS-ul din zona roșie direct la 60 constant.

Trade-off-ul sincer cu FlashList: FlashList e excelent, dar necesită proprietatea estimatedItemSize. Dacă înălțimea cardurilor variază extrem de mult și e greu de estimat, vei avea sărituri urâte la scroll (layout shifts). În cazuri cu layout-uri imprevizibile, un FlatList bine reglat din windowSize și maxToRenderPerBatch poate fi mai stabil vizual.

Voi cum abordați profiling-ul pe React Native? Folosiți Profiler-ul din React DevTools sau mergeți direct pe Flipper și Perf Monitor-ul nativ?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.