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

React Native performance: Când ajută memo, useCallback și FlashList cu adevărat

De Ștefan Iliescu, 6 aug. 2026 · 10 vizualizări · 2 like-uri

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

type Product = { id: string; title: string };

// 1. Componenta copil e memoată
const ProductCard = memo(({ item, onPress }: { item: Product; onPress: (id: string) => void }) => {
  return (
    <Pressable onPress={() => onPress(item.id)} style={{ padding: 16 }}>
      <Text>{item.title}</Text>
    </Pressable>
  );
});

export const ProductList = ({ data }: { data: Product[] }) => {
  // 2. Callback-ul păstrează referința stabilă
  const handlePress = useCallback((id: string) => {
    console.log('Selected:', id);
  }, []);

  const renderItem = useCallback(({ item }: { item: Product }) => (
    <ProductCard item={item} onPress={handlePress} />
  ), [handlePress]);

  // 3. FlashList reciclează celulele nativ
  return (
    <FlashList
      data={data}
      renderItem={renderItem}
      estimatedItemSize={72}
      keyExtractor={(item) => item.id}
    />
  );
};

Salutare! Săptămâna trecută am terminat de curățat un feed dintr-o aplicație e-commerce în React Native unde scroll-ul agăța masiv pe telefoane mid-range. Am redus timpul de execuție pe JS thread de la 45ms per frame la sub 5ms. Vă spun mai jos ce a funcționat cu adevărat și ce mituri legate de performanță am dărâmat pe parcurs.

Mitul useCallback pus peste tot

Am văzut cod în producție unde fiecare handler de click era învelit în useCallback, dar componenta copil primea props noi la fiecare render. Să fim clari: useCallback NU oprește re-renderarea componentei curente și nici a copiilor, decât dacă copiii sunt memoați explicit cu React.memo.

La un proiect cu vreo 8k useri activi zilnic, aveam o listă de notificări. Fiecare card avea un buton de "Read". Fără React.memo pe componenta de card, degeaba foloseam useCallback în părinte — toate cele 30 de carduri vizibile își făceau re-render la orice schimbare minoră de state global.

Regula e simplă: folosești useCallback DOAR când pasezi funcția ca prop către o componentă copil învelită în React.memo, sau când e dependență într-un useEffect. Altfel, doar adaugi overhead creând closure-uri degeaba.

useMemo salvează CPU-ul, dar nu pentru obiecte banale

Nu pune useMemo pe un obiect simplu de configurare sau un stil inline de 3 linii. Overhead-ul de a verifica array-ul de dependențe la fiecare render costă uneori mai mult decât recrearea obiectului în JS Engine.

În schimb, dacă ai o listă de 1.000 de produse și faci .filter().sort() în render, acolo useMemo e sfânt. Fără el, la fiecare caracter tastat într-un search bar, blochezi thread-ul de JS pentru 30-50ms doar ordonând un array.

FlashList vs FlatList: Trecerea de la 20 FPS la 60 FPS

Dacă aveți liste lungi și încă folosiți FlatList din core-ul de React Native, pierdeți performanță gratuit. FlatList creează și distruge componente pe măsură ce faci scroll. Asta înseamnă că la scroll rapid pe un Android ieftin, aplicația nu mai dovedește să monteze elementele și apar pătrate albe pe ecran.

FlashList (de la Shopify) funcționează diferit: reciclează componentele existente și le schimbă doar datele, exact ca un RecyclerView nativ pe Android.

Trade-off-ul sincer? FlashList are nevoie de o proprietate estimatedItemSize. Dacă elementele voastre din listă au înălțimi extrem de dinamice (de exemplu, postări cu 0, 1 sau 5 imagini încărcate async) și nu le calculați bine dimensiunea inițială, mai apar scurte blițuri vizuale când le reciclează. Dar pentru 95% din cazuri, e net superior.

Măsoară înainte să optimizezi

Nu optimiza orbește. Pornește Perf Monitor-ul din In-App Dev Menu sau deschide React DevTools Profiler. Dacă o componentă se randeză în 0.2ms, nu-ți bate capul cu useMemo. Optimizează doar acolo unde simți un scurt lag la atingere sau unde Frame Rate-ul pe JS scade sub 55 FPS.

Voi mai folosiți FlatList pe proiecte noi sau ați trecut definitiv la FlashList?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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