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

FlatList vs FlashList pe Android entry-level: Ce arată Perf Monitor în realitate

De Cosmin Rotaru, 23 mai 2026 · 6 vizualizări · 3 like-uri

Postat 23 mai 2026
typescript
import React, { useMemo } from 'react';
import { FlashList } from '@shopify/flash-list';
import { ProductCard } from './ProductCard';

export const ProductFeed = ({ items }) => {
  // Calculăm o medie realistă pentru a evita layout shifts la scroll
  const averageHeight = useMemo(() => {
    return items.length > 0 ? 280 : 150;
  }, [items]);

  return (
    <FlashList
      data={items}
      renderItem={({ item }) => <ProductCard item={item} />}
      estimatedItemSize={averageHeight}
      keyExtractor={(item) => item.id.toString()}
      getItemType={(item) => item.type} // Ajută masiv la reciclarea corectă a layout-urilor diferite
      drawDistance={500} // Pre-randare pe Android entry-level pentru a evita ecranele albe
    />
  );
};

Salutare tuturor. Săptămâna trecută m-am lovit de o problemă clasică pe care probabil mulți o cunoașteți: un feed infinit într-o aplicație de e-commerce cu vreo 12.000 de produse, pline de imagini și detalii dinamice. Pe iPhone-ul meu de test totul zbura la 120 FPS, fără nicio ezitare. Când am pus însă aplicația pe un Samsung A12 de 600 de lei (pe care îl țin special în sertar pentru teste de performanță pe hardware slab), s-a terminat rapid șmecheria. FlatList-ul default din React Native abia scotea 18-20 FPS pe JS thread în timpul unui scroll mai agresiv. Aplicația părea complet blocată.

Am decis să trec feed-ul pe FlashList, biblioteca celor de la Shopify. Se laudă peste tot că e de 5 ori mai rapidă decât FlatList-ul nativ. Am vrut să văd dacă e doar marketing sau chiar face diferența pe hardware low-end, așa că am pornit Perf Monitor-ul din developer menu și am început să măsor pe bune.

Ce am descoperit în Perf Monitor

Pe Android-ul ăsta ieftin, FlatList are o mare problemă arhitecturală. Când utilizatorul dă scroll rapid, lista creează și distruge componente în neștire. Asta înseamnă că garbage collector-ul rulează constant în fundal, iar JS thread-ul pur și simplu moare în chinuri.

Cu FlatList, imediat ce treceam de primele 50 de produse, UI thread-ul scădea pe la 42 FPS, cu drop-uri violente până la 25 în timp ce se încărcau imaginile mari. JS thread-ul murea complet pe la 12-15 FPS, făcând aplicația să nu mai răspundă la atingeri. În plus, memoria RAM creștea constant cu vreo 80MB în doar două minute de scroll continuu.

Am înlocuit FlatList cu FlashList. Schimbarea e destul de simplă la nivel de API, dar logica de sub capotă e complet diferită. FlashList nu distruge componentele care ies din ecran, ci le reciclează, modificându-le doar proprietățile prin procesul de recycling.

Rezultatele pe același Samsung A12 au fost vizibile imediat. UI thread-ul a rămas stabil la 58-60 FPS. JS thread-ul nu a scăzut sub 48 FPS, chiar și la cel mai rapid scroll posibil. Consumul de memorie s-a stabilizat complet pentru că am scăpat de garbage collection-ul agresiv. Diferența la utilizarea reală este uriașă: au dispărut acele ecrane albe enervante care apăreau când FlatList-ul nu ținea pasul cu randarea.

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

Sună prea frumos ca să fie adevărat, nu? FlashList e excelent, dar vine cu niște bătăi de cap destul de mari la implementare.

Cea mai mare problemă este proprietatea estimatedItemSize. Dacă nu îi oferi o valoare extrem de precisă, lista o ia razna complet. Începe să sară scroll-ul aiurea când randezi elemente cu înălțimi dinamice (de exemplu, unele produse au badge-uri de reducere sau titluri pe trei rânduri, altele nu).

Dacă ai layout-uri foarte diferite în listă, calculul devine un mic coșmar. Am pierdut vreo 4 ore doar ca să calibrez estimările și să rezolv un bug vizual unde elementele se suprapuneau preț de o secundă când utilizatorul dădea scroll înapoi sus. De asemenea, dacă folosești keyExtractor greșit, dezactivezi practic reciclarea și anulezi tot câștigul de performanță.

Merită migrarea?

Dacă aplicația ta rulează doar pe telefoane de top, FlatList-ul configurat corect este absolut ok și îți salvează timp la dezvoltare. În schimb, dacă ai utilizatori pe Android-uri ieftine (cum e cazul majorității aplicațiilor B2C din România), FlashList e pur și simplu obligatoriu. Am salvat cam 30% din timpul de randare și am stabilizat frame rate-ul pe terminalele low-end.

Voi ce folosiți pentru liste complexe? Ați rămas pe FlatList-ul nativ optimizat la sânge din proprietăți (precum windowSize sau maxToRenderPerBatch) sau ați trecut direct la FlashList?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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