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

FlatList vs FlashList pe Android ieftin: Cum am salvat 30 FPS în producție

De Cosmin Rotaru, 27 mai 2026 · 5 vizualizări · 2 like-uri

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

interface Product {
  id: number;
  title: string;
  price: string;
}

const ProductFeed = ({ products }: { products: Product[] }) => {
  return (
    <FlashList
      data={products}
      renderItem={({ item }) => (
        <View style={{ height: 120, padding: 10 }}>
          <Text>{item.title}</Text>
          <Text>{item.price}</Text>
        </View>
      )}
      // OBLIGATORIU: Valoare medie estimată pentru a preveni layout jumps
      estimatedItemSize={120}
      keyExtractor={(item) => item.id.toString()}
    />
  );
};

Am avut de optimizat recent un feed de produse pentru o aplicație de e-commerce cu vreo 15.000 de utilizatori activi lunar. Pe iPhone-ul meu de test totul mergea brici, dar când am pus aplicația pe un Motorola Moto E22 (un entry-level clasic, cu procesor MediaTek ieftin), feed-ul s-a transformat într-un slideshow dureros.

Foloseam clasicul FlatList din React Native. La un scroll mai rapid, ecranul devenea complet alb timp de 2-3 secunde în timp ce JS thread-ul încerca cu disperare să randeze următoarele carduri. Am pornit Perf Monitor-ul din developer menu și realitatea m-a lovit direct în față: UI thread-ul oscila pe la 20 FPS, iar JS thread-ul murea complet, ajungând frecvent la 2-3 FPS.

De ce moare FlatList pe hardware slab?

Problema cu FlatList este că, sub capotă, nu reciclează view-urile native. Când un element iese din ecran, el este demontat (unmount), iar când intră unul nou, React trebuie să creeze de la zero noi noduri de Virtual DOM și să le trimită peste bridge către nativ. Pe un procesor low-end, acest proces continuu de montare și demontare pur și simplu blochează thread-ul de JavaScript.

Practic, garbage collector-ul rulează non-stop ca să curețe nodurile vechi, în timp ce procesorul încearcă să calculeze layout-ul pentru elementele noi. Rezultatul? Frame drops masive și ecrane albe.

Trecerea la FlashList: Cifrele din Perf Monitor

Am decis să înlocuiesc FlatList cu FlashList de la Shopify. Migrarea e destul de simplă, API-ul fiind aproape identic, dar rezultatele pe ecran m-au lăsat mască. Am măsurat ambele liste pe același dispozitiv Motorola low-end, în aceleași condiții de scroll rapid.

Iată ce a raportat Perf Monitor:

  • FlatList: UI thread pe la 22 FPS, JS thread pe la 4 FPS (zone albe masive, lag de jumătate de secundă la atingerea ecranului în timp ce dădeam scroll).
  • FlashList: UI thread stabil la 56 FPS, JS thread la 45 FPS (scroll fluid, zonele albe apar extrem de rar și dispar aproape instant).

Am economisit cam 40% din utilizarea CPU pe JS thread. Secretul celor de la Shopify este reciclarea reală a celulelor native (asemănător cu RecyclerView din Android sau UICollectionView pe iOS). Elementele care ies din ecran nu sunt distruse, ci sunt reținute în memorie și repopulate cu noile date care intră în viewport.

Trade-off-ul de care trebuie să știi

Sună prea frumos ca să fie adevărat? Cam este. FlashList vine cu niște cerințe stricte de care m-am lovit rapid.

Cea mai mare bătaie de cap este proprietatea estimatedItemSize. Trebuie să îi dai o valoare medie cât mai apropiată de realitate. Dacă elementele tale au înălțimi foarte dinamice (de exemplu, unele carduri au text de trei rânduri, altele au imagini mari, altele doar un titlu), FlashList va face "layout jumps" extrem de vizibile în timpul scroll-ului, pentru că își recalculează pozițiile din mers.

De asemenea, atenție mare la state-ul intern al componentelor din listă. Deoarece celulele sunt reciclate, dacă ai un checkbox bifat într-un rând și dai scroll, s-ar putea ca acea celulă să apară mai jos complet bifată pentru un alt produs, dacă nu îți gestionezi corect state-ul prin props curate și nu resetezi starea la nivel de componentă.

Voi ce folosiți pentru liste complexe? Ați rămas pe FlatList sau ați făcut trecerea la FlashList în producție?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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