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

De ce ți se agață lista în React Native: Memoizare și FlashList pe bune

De Alin Pătrașcu, 25 apr. 2026 · 1 vizualizări · 3 like-uri

Postat acum 2 zile
typescript
import React, { memo, useCallback } from 'react';
import { FlashList } from '@shopify/flash-list';

const ProductItem = memo(({ item, onPress }) => {
  return (
    <TouchableOpacity onPress={() => onPress(item.id)}>
      <Text>{item.name}</Text>
    </TouchableOpacity>
  );
});

const MyList = ({ data }) => {
  // useCallback e util aici pentru că ProductItem e memoizat
  const handlePress = useCallback((id) => {
    console.log('Pressed:', id);
  }, []);

  return (
    <FlashList
      data={data}
      renderItem={({ item }) => <ProductItem item={item} onPress={handlePress} />}
      estimatedItemSize={70}
      keyExtractor={(item) => item.id.toString()}
    />
  );
};

M-am lovit de multe ori de problema asta: scrii cod curat, urmezi toate tutorialele, dar când ajungi la o listă cu 200 de elemente, scroll-ul devine un coșmar. E incredibil de frustrant să vezi cum un iPhone de 1000 de euro agață la un amărât de feed de știri. Am pățit asta la un proiect cu peste 15k de produse, unde clientul se plângea că aplicația „nu se simte nativă”.

Prima greșeală pe care o văd la mulți juniori și chiar la developeri mid e folosirea excesivă a useMemo și useCallback. Există mitul ăsta că dacă învelești totul în memoizare, aplicația va zbura. Total fals. Am avut un modul de filtrare unde adăugarea de useCallback la fiecare funcție mică a crescut timpul de inițializare cu aproximativ 15%. De ce? Pentru că engine-ul de JS are și el de lucru să stocheze acele referințe și să facă verificările de egalitate la fiecare re-render. Practic, plătești un preț în memorie și CPU pentru o optimizare care s-ar putea să nu fie necesară.

Când folosim cu adevărat memoizarea?

Regula mea de aur e simplă: nu optimizez până nu văd probleme în Profiler-ul din Flipper. Dacă am un component „greu”, cum e o hartă sau un grafic complex, acolo React.memo e sfânt. Dar dacă e doar un buton sau un text, lasă-l să facă re-render. E mult mai ieftin să randezi un nod virtual simplu decât să pui motorul de JS să compare obiecte complexe de props la fiecare frame.

useCallback devine critic doar atunci când pasezi funcții către componente copii care sunt deja învelite în memo. Dacă nu faci asta, funcția se va recrea oricum, dar măcar nu mai consumi memorie extra să o „salvezi”. Trade-off-ul e mereu între stabilitatea referențială și consumul de memorie.

FlatList vs FlashList: Schimbarea la față

FlatList e bunicul framework-ului. E stabil, dar are o problemă structurală: nu reciclează view-urile nativ așa cum o face un RecyclerView pe Android sau UITableView pe iOS. El doar „distruge” componentele care ies din ecran și creează altele noi. La o listă lungă cu imagini, asta „omoară” RAM-ul și procesorul.

Când am trecut la FlashList (biblioteca celor de la Shopify), am economisit cam 30% la build-ul de memorie în runtime. FlashList refolosește aceleași componente native și doar le injectează date noi. E o diferență masivă de la cer la pământ. Totuși, FlashList vine cu un „catch”: trebuie să-i dai un estimatedItemSize. Dacă pui o valoare la întâmplare, o să ai un scroll sacadat („jumps”) pentru că motorul de layout nu știe să calculeze corect zonele de scroll. Eu fac de obicei o medie: măsor primele 10 elemente și pun valoarea aia.

Optimizarea listelor în producție

Pe lângă alegerea componentei de listă, contează enorm ce pui în ea. Dacă item-ul tău de listă e un „monstru” de 500 de linii de cod cu logică internă de business, nicio bibliotecă din lume nu te salvează. În proiectul cu 15k produse, am reușit să ducem lista de la 25 FPS la un 60 FPS constant doar prin mutarea logicii grele în afara listei și folosirea memo strict pe componenta de rând.

Nu uita de keyExtractor. Dacă folosești index-ul array-ului ca key, React Native va re-rendera toată lista la orice modificare a ordinii. E cea mai rapidă cale să transformi un telefon high-end într-o cărămidă încinsă. Folosește ID-uri unice din baza de date, mereu.

Care a fost cel mai mare „lag” pe care l-ați rezolvat într-o listă de React Native și ce a fost de vină?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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