A ScrollView with map renders every child up front. ScrollView vs FlatList measured the cost: 2,000 text rows took almost six seconds before the screen could lay out. A virtualized list keeps a window of rows around the viewport, mounted and laid out, and replaces everything else with blank space of the right height. As the user scrolls, rows entering the window are rendered and rows leaving it are unmounted, so memory and render work stay roughly constant however long the data is.
VirtualizedList measures the window in viewport heights: windowSize (default 21) means ten screens above, the visible one and ten below. It renders initialNumToRender rows (10) first, then fills the window in batches of maxToRenderPerBatch (10) at most every updateCellsBatchingPeriod (50 ms), rendering the visible area at high priority. The price is visible when the user flings faster than JavaScript can render: blank rows flash until the batch arrives. Row state is also lost when a row leaves the window, so keep state that must survive in the data or a store, not in the row component.