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

React Native performance: Când ajută memo/useCallback și de ce FlatList te îngroapă

De Alin Pătrașcu, 24 iul. 2026 · 5 vizualizări · 2 like-uri

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

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

// 1. Componenta copil trebuie sa fie memoizata
const ProductCard = memo(({ item, onPress }: { item: Product; onPress: (id: string) => void }) => (
  <Pressable onPress={() => onPress(item.id)} style={styles.card}>
    <Text>{item.title}</Text>
  </Pressable>
));

export const ProductList = ({ items }: { items: Product[] }) => {
  // 2. Referinta stabila pentru handler
  const handlePress = useCallback((id: string) => {
    console.log('Product clicked:', id);
  }, []);

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

  return (
    <FlashList
      data={items}
      renderItem={renderItem}
      estimatedItemSize={70}
      keyExtractor={(item) => item.id}
    />
  );
};

const styles = StyleSheet.create({
  card: { height: 70, padding: 16, borderBottomWidth: 1 }
});

Am văzut prea multe PR-uri în care colegii pun useCallback și useMemo pe absolut orice funcție sau obiect, crezând că așa optimizează aplicația. Adevărul e că optimizarea prematură în React Native mai mult încurcă, iar memoizarea are un cost ascuns de memorie și CPU. Hai să vedem ce funcționează cu adevărat în producție și ce e doar zgomot.

Buba cu React.memo, useCallback și useMemo

Acum vreun an lucram la o aplicație de e-commerce cu vreo 12.000 de produse în catalog. La fiecare scroll mai rapid sau filtru aplicat, UI-ul agăța sesizabil și oprea animațiile — cobora frecvent sub 30 FPS pe telefoane mid-range. Prima reacție a echipei a fost instinctivă: "punem React.memo pe cardul de produs și useCallback pe handler-ul de onPress". Ghici ce? Nicio diferență masivă.

useCallback nu face codul din interiorul funcției mai rapid. Doar păstrează aceeași referință între re-renderări. Dacă componenta părinte își schimbă alt prop instabil (de exemplu un style={{ margin: 8 }} declarat inline), React.memo re-evaluează props-urile, vede o referință nouă și randează din nou oricum. Am pierdut timp și am adăugat boilerplate degeaba.

Regula mea simplă după 10 ani de JS/TS:

  1. Folosește useMemo și useCallback DOAR când pasezi referințe către copii frunză care sunt deja împachetați în React.memo și au un render scump (hărți, liste, grafice complex desenate).
  2. Folosește useMemo pentru calcule matematice sau filtrări pe liste mari (peste 500-1000 de elemente). Pentru un items.filter(x => x.active) pe o listă de 15 elemente, memoizarea e mai scumpă decât filtrarea în sine.

De la FlatList la FlashList — diferența de la cer la pământ

Dacă ai o listă lungă și folosești FlatList, nicio memoizare din lume nu te salvează pe Android. FlatList creează și distruge noduri native pe măsură ce faci scroll. Rezultatul e clasic: ecran alb când dai scroll rapid (blank spaces) și consum de memorie RAM scăpat de sub control.

Am migrat lista aia de 12k produse la FlashList (librăria celor de la Shopify). Rezultatul direct a fost o scădere a utilizării memoriei RAM cu 35%, iar JS thread-ul a rămas la 60 FPS chiar și pe un Samsung A51 obosit. FlashList nu distruge views-urile când ies din ecran, ci le reciclează la nivel nativ, exact ca RecyclerView pe Android sau UICollectionView pe iOS.

Trade-off-ul sincer? FlashList e genial, dar e mai sensibil la structura de layout. Trebuie să-i dai un estimatedItemSize cât mai aproape de realitate. Dacă ai iteme cu înălțimi ultra-dinamice care variază de la 50px la 400px și pui o valoare greșită, o să ai mici jumping-uri vizuale urâte când dai scroll înapoi.

Tu ce trucuri folosești când începe JS thread-ul să agățeze pe Android?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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