Current behavior
FlashList is taking too much time on first render compared to FlatList: Flashlit is taking around 3 seconds Flatlist is taking 300ms
Expected behavior
FlashList should take not much time on first render. for FlatList change only FlashList to Flatlist and remove estimatedItemSize and estimatedListSize
To Reproduce
this is my code:
import React from 'react';
import { Dimensions, FlatList } from 'react-native';
import { NewCarCard } from 'features/cars/new-cars/new-car-card';
import { Line } from 'ui/dividers/line';
import { useNewCars } from 'features/cars/new-cars/hooks/use-new-cars';
import { NewCarsVerticalListShimmer } from 'features/cars/new-cars/shimmers/new-cars-vertical-list.shimmer';
const deviceWidth = Dimensions.get('window').width;
const deviceHeight = Dimensions.get('window').height;
interface Props {
onPress: () => void;
scrollEnabled: boolean;
}
export function NewCarsVerticalList(props: Props) {
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = useNewCars();
const newCarsFlatted = data?.pages.map(page => page.data.data.items).flat();
const loadNext = React.useCallback(() => {
if (hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
const renderItem = ({ item }) => {
return (
<React.Fragment>
<NewCarCard newCar={item} onPress={props.onPress} />
<Line />
</React.Fragment>
);
};
const renderListFooter = () => {
if (isFetchingNextPage) {
return (
// Show shimmer when isFetchingNextPage is true
<>
<NewCarsVerticalListShimmer />
<NewCarsVerticalListShimmer />
</>
);
}
return null;
};
return (
<FlashList
scrollEnabled={props.scrollEnabled || false}
data={newCarsFlatted}
showsVerticalScrollIndicator={false}
estimatedItemSize={deviceHeight * 0.45}
estimatedListSize={{
height: deviceHeight * 0.45 * newCarsFlatted.length,
width: Dimensions.get('screen').width,
}}
renderItem={({ item }) => renderItem({ item })}
keyExtractor={item => item?.id} // Make sure to use a string for the key
onEndReached={loadNext}
onEndReachedThreshold={0.7}
ListFooterComponent={renderListFooter}
/>
);
}
export default React.memo(NewCarsVerticalList);
Platform:
- iOS
- Android
Environment
- "react-native": "0.72.3"
- "@shopify/flash-list": "^1.6.1",
The right answer was: estimatedListSize should refer to number of possible available items in the screen and not the whole dataset
In my case only 2 elements of the list could be shown in screen.