FlashList is taking too long in first render compared to FlatList

335 views Asked by At

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",
1

There are 1 answers

0
Zero0 On BEST ANSWER

The right answer was: estimatedListSize should refer to number of possible available items in the screen and not the whole dataset

estimatedListSize={{
        height: deviceHeight * 0.45 * newCarsFlatted.length,
        width: Dimensions.get('screen').width,
      }}

In my case only 2 elements of the list could be shown in screen.