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

De ce îți agață lista în React Native? De la FlatList la FlashList și optimization hooks pe bune

De Elisabeta Stan, 1 iul. 2026 · 11 vizualizări · 2 like-uri

Postat 1 iul. 2026
typescript
import React, { memo, useCallback } from 'react';
import { Text, TouchableOpacity, StyleSheet } from 'react-native';

interface ButtonProps {
  onPress: (id: string) => void;
  id: string;
  title: string;
}

// Memoizare corectă: componenta se re-randează doar dacă props-urile se schimbă
export const MemoizedButton = memo(({ onPress, id, title }: ButtonProps) => {
  return (
    <TouchableOpacity 
      style={styles.button} 
      onPress={() => onPress(id)}
    >
      <Text>{title}</Text>
    </TouchableOpacity>
  );
});

const styles = StyleSheet.create({
  button: {
    padding: 12,
    backgroundColor: '#007AFF',
    borderRadius: 8,
  },
});

Am văzut prea multe proiecte în care lumea pune useCallback peste tot ca un fel de talisman împotriva lag-ului. Adevărul e că optimizarea prematură în React Native nu doar că e inutilă, dar uneori chiar strică performanța. Am pățit-o și eu pe o aplicație de livrări unde aveam liste lungi și telefoane de buget.

Hai să dăm la o parte miturile din tutorialele de pe YouTube și să vedem ce funcționează cu adevărat în producție.

Mitul useCallback și useMemo

Mulți cred că dacă pun useCallback pe o funcție de onPress, gata, au salvat frame-urile. Fals. Am avut un ecran cu vreo 150 de produse unde adăugarea de useCallback pe butoane nu a mișcat FPS-ul cu niciun milisecundă. De ce?

Pentru că componenta părinte tot se re-randa, iar child-ul (butonul) nu era învelit în React.memo. useCallback ajută DOAR dacă componenta copil folosește React.memo și previne re-randarea prin compararea props-urilor. Altfel, doar adaugi overhead de memorie. Motorul de JS trebuie să ruleze logica de comparație a dependențelor la fiecare render degeaba.

Regula mea de aur: folosesc useMemo doar pentru calcule grele (cum ar fi sortarea sau filtrarea unui array de peste 500 de itemi) și useCallback exclusiv când pasez funcții către copii memoizați sau în interiorul dependențelor de la useEffect.

React.memo și capcana obiectelor inline

React.memo e util, dar are un cost ascuns. El face o comparare superficială (shallow comparison) a props-urilor. Dacă trimiți un obiect inline ca prop, compararea va da mereu false, iar memoizarea devine complet inutilă.

La un proiect cu 8.000 de utilizatori activi pe zi, aveam un feed unde trimiteam stiluri inline direct în componenta de item: <ProductItem style={{ margin: 10 }} />. Chestia asta simplă făcea ca React.memo să ruleze verificarea degeaba la fiecare scroll, mâncând cam 12-15ms pe frame. Soluția? Stiluri declarate în afara componentei sau folosite prin StyleSheet.create.

FlatList vs FlashList: Trecerea la nivelul următor

FlatList-ul nativ din React Native devine rapid sufocat când lista depășește 100-200 de elemente complexe, mai ales pe Android-uri ieftine. El randează elementele asincron și le distruge pe cele care ies din ecran. Asta lasă des acele zone albe („blank spaces”) când utilizatorul dă scroll rapid.

Am înlocuit FlatList cu @shopify/flash-list pe o listă cu 2.000 de tranzacții financiare. Rezultatul a fost instant: am trecut de la un FPS jalnic de 20-25 pe un Samsung A12 direct la un 60 FPS stabil.

FlashList nu distruge componentele, ci le reciclează layout-ul (concept similar cu RecyclerView din Android).

Trade-off-ul sincer cu FlashList

Nimic nu e gratis. FlashList are nevoie de un estimatedItemSize. Dacă elementele tale au înălțimi extrem de dinamice (de exemplu, postări pe un wall de social media cu text variabil și imagini opționale), calculul devine anevoios. Dacă aproximarea ta e proastă, vei avea „jumpy scroll” (sărituri ciudate pe ecran) când utilizatorul navighează prin listă.

Pentru liste simple și uniforme, FlashList e „no-brainer”. Pentru chestii ultra-dinamice, s-ar putea să fii nevoit să optimizezi la sânge FlatList-ul vechi folosind getItemLayout și windowSize redus la 5 sau 7.

Tu cum abordezi listele lungi în React Native? Ai trecut deja la FlashList sau ai reușit să îmblânzești FlatList-ul standard?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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