FlatList
Profile: GTK · Backed by: a windowed core over ScrollView

Supported props:
- Virtualization (
estimatedItemSizeorgetItemLayout,windowSize/initialNumToRenderas the primary scroll-performance knobs,maxToRenderPerBatch/updateCellsBatchingPeriod). data/renderItem/keyExtractor/extraData,ItemSeparatorComponent.CellRendererComponent— RN's per-cell wrapper. The list still hands it the cell's absolutestyleand theonLayoutthat measures it, and both must be applied, which is whatreact-native-draggable-flatlistbuilds its design on.ListHeader/Footer/EmptyComponent,onEndReached(-Threshold).onViewableItemsChanged/viewabilityConfig(ViewToken).inverted— RN's chat semantics: the list opens atdata[0]and stays pinned on prepend.refreshing/onRefresh,horizontal,stickyHeaderIndices.- A ref exposing
scrollToIndex/scrollToItem/scrollToOffsetplusscrollTo/scrollToEnd(FlatListHandle) — the scroll half of aScrollViewref, not the geometry half: a windowed list is a composite overScrollViewand owns no widget of its own, so measure theScrollViewor a cell instead.
Differs from react-native:
- 1000 rows mount windowed in roughly 120 ms.
windowSizedefaults to 11, not RN's 5 — desktop has no mobile memory pressure, and a wider window means fewer mount-and-reflow bursts per scrolled pixel (measured: 21% less churn, late frames down from 10/s to 7.7/s).- Rows beyond the visible ones mount
maxToRenderPerBatch(10) at a time, everyupdateCellsBatchingPeriod(50) ms, so a flick or a longscrollToOffsetfills its window over several frames instead of stalling one. - There is no pull gesture —
onRefreshis always app-triggered. - An inverted list shorter than its viewport anchors to the top, not the bottom.
CellRendererComponentdoes not apply to a sticky cell (stickyHeaderIndices), because pinning reorders the cell's real GTK widget — the sticky container has to be the cell.
Traces and the full scroll-phase measurement method are recorded in the
repository's docs/research/ notes, referenced from the source.