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

FlatList vs FlashList pe Android ieftin: Cum am salvat FPS-ul cu Perf Monitor

De Florin Manea, 11 iun. 2026 · 15 vizualizări · 3 like-uri

Postat 11 iun. 2026
typescript
import React from 'react';
import { Text, View } from 'react-native';
import { FlashList } from '@shopify/flash-list';

interface Item {
  id: string;
  title: string;
}

const ImprovedList = ({ items }: { items: Item[] }) => {
  return (
    <FlashList
      data={items}
      renderItem={({ item }) => (
        <View style={{ height: 80, padding: 10 }}>
          <Text>{item.title}</Text>
        </View>
      )}
      estimatedItemSize={80} // Valoare critică pentru performanță
      keyExtractor={(item) => item.id}
    />
  );
};

Salutare. Am tot văzut discuții teoretice despre performanța listelor în React Native, așa că am decis să fac un test real, pe "fier", nu în simulator. Am pus față în față clasicul FlatList și FlashList de la Shopify pe un telefon de acum 3 ani, un Xiaomi Redmi 9 cu 3GB RAM. Dacă pe un iPhone 15 Pro ambele se mișcă la 120Hz de zici că-s native, pe entry-level Android se dă adevărata bătălie.

Problema cu FlatList pe hardware slab

La un proiect recent cu peste 8.000 de înregistrări într-un feed, am avut de randat carduri complexe. Fiecare item avea un avatar, două rânduri de text, un badge și un buton de acțiune. Nimic ieșit din comun.

Cu FlatList, pe măsură ce dădeam scroll rapid pe Redmi 9, JS thread-ul pur și simplu murea. Am activat Perf Monitor din developer menu și am văzut cum FPS-ul pe JS scădea dramatic de la 60 direct la 14-18 FPS. UI thread-ul rămânea blocat la 20 FPS din cauză că garbage collector-ul încerca disperat să elibereze nodurile de memorie nefolosite. Practic, FlatList doar ascunde componentele din ecran (le face unmount), dar overhead-ul de reconciliere în React rămâne uriaș. Utilizatorul vedea acele ecrane albe goale (blank spaces) și un lag de aproape o secundă la scroll.

Trecerea la FlashList și rezultatele

Am decis să rescriu lista folosind @shopify/flash-list. Integrarea e rapidă pentru că API-ul e aproape identic, dar vine cu o cerință critică: trebuie să-i dai un estimatedItemSize.

După ce am configurat dimensiunea estimată, am rulat din nou testul pe același Xiaomi. Diferența a fost de la cer la pământ. Pe Perf Monitor, JS thread-ul nu a mai scăzut sub 52 FPS, chiar și la scroll agresiv. UI thread-ul a stat stabil la 58-60 FPS. Am eliminat complet zonele albe de așteptare, iar consumul de RAM a scăzut cu aproape 30%. Asta se întâmplă pentru că FlashList nu distruge și nu recreează componentele din DOM-ul virtual, ci le reciclează (reutilizează aceleași views native, schimbând doar datele).

Trade-off-ul de care nu vorbește nimeni

Sună prea frumos ca să fie adevărat? Cam este. FlashList funcționează excepțional, dar vine cu niște compromisuri mari pe care trebuie să le accepți:

  • Starea internă a celulelor: Deoarece celulele sunt reciclate, dacă ai componente cu stare internă (de exemplu, un buton de "Like" care își schimbă culoarea local prin useState), când dai scroll, starea aia s-ar putea să rămână activă pe un alt rând care tocmai a apărut pe ecran. Trebuie să muți absolut toată starea în store sau în datele primite ca prop.
  • Estimated Item Size: Dacă dimensiunea estimată e greșită (de exemplu, pui 100 în cod, dar cardurile tale au de fapt 300px înălțime), lista va avea un comportament de "săritură" (layout jumps) extrem de deranjant la scroll. Devine un coșmar dacă ai înălțimi complet dinamice, bazate pe text generat de utilizatori.

Concluzia mea

Dacă ai o listă simplă, sub 100 de elemente, rămâi pe FlatList. Nu merită să te complici cu reciclarea și managementul stării. În schimb, dacă ai liste infinite, feed-uri sau e-commerce și vrei ca aplicația ta să nu agațe pe telefoane de 600 de lei, FlashList e obligatoriu.

Voi cum ați rezolvat problemele de jumpy layout la FlashList când înălțimile variază masiv?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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