Large amount of data affecting performance - react-native

I have a huge list of data that I want to send to a different screen when I am transitioning, but the problem I am experiencing is a performance issue. Like when I transition, the response time takes about 2-3 seconds for it to transfer and it's not very responsive.
Here's my code setup of what I have:
const PopularNow = (props) => {
return (
<FlatList
data={props.data}
keyExtractor={item => item.id.toString()} //id.toString()
horizontal
showsHorizontalScrollIndicator={false}
style={{paddingLeft: 10}}
ItemSeparatorComponent={() => <ItemSeparator width={20} />}
ListHeaderComponent={() => <ItemSeparator width={20} />}
ListFooterComponent={() => <ItemSeparator width={50} />}
renderItem={({item}) => {
if (item.cover.image_id) {
return (
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
props.navigation.push('GamePreview', {
gameName: item.name,
gameCover: item.cover.image_id,
gameReleased: item.first_release_date,
total_Rating: item.total_rating,
gamePlatforms: item.platforms,
gameSummary: item.summary,
similarGames: item.similar_games,
Screenshot: item.screenshots,
Videos: item.videos,
====> involveCompanies: item.involved_companies,
gameGenres: item.genres,
artworks: item.artworks,
age_Rating: item.age_ratings,
age_Rating_Description: item.age_ratings,
gameModes: item.game_modes,
multiplayerModes: item.multiplayer_modes,
playerPerspectives: item.player_perspectives,
gameEngine: item.game_engines,
gameSeries: item.collection,
gameDLC: item.dlcs,
})
}>
<Image
resizeMode="cover"
style={styles.containerGames}
source={{uri: getImage(item.cover.image_id)}}
/>
</TouchableOpacity>
);
}
}}
/>
}
)
the involved_companies is what makes the screen transition very slow because of the amount of companies I invoke from the api. When I comment this out the performance is very responsive. I want to know if there is an alternative to improve performance with a large amount of data.

I would suggest not to pass the whole data to the next screen. The listing should only display what it's need to be display (based on your design).
All you need is just to pass the id, so in the GamePreview screen will have to call another API to get game preview detail.
By doing this, you GamePreview screen is deeplink-able because you may allow user to share the game preview detail link. If using current way, your link have to contains all the params and which is not possible because some property is object.
It should work when reduce amount of unnecessary data. If it's still doesn't work for your case, you can try this awesome library flash-list

Related

How To get 2 Flat list To attract instead of repel

So I am working on a react native project and have created a modal.
this modal shows the selected and unselected Tasks. Now For this I created a View With two flat lists as shown:
<View style={styles.tasksListContainer}>
<FlatList
data={tasksToShow}
renderItem={(itemData) => {
if (!itemData.item.usedUp) {
return <TaskIsNotBeingUsed itemData={itemData} onTaskSelect={onTaskSelect}/>
}
}}
/>
<FlatList
data={tasksToShow}
renderItem={(itemData) => {
if (itemData.item.usedUp) {
return <TaskIsBeingUsed itemData={itemData}/>
}
}}
/>
</View>
Now the problem is that all the Selected Tasks And None Selected Tasks have some kind of space between them can anyone tell me why?
Because you're using the same array and sometimes return something but sometimes return nothing so there's empty items. You can do it like that:
// Unchecked
<FlatList
data={tasksToShow.filter(itemData => !itemData.usedUp)}
// Checked
<FlatList
data={tasksToShow.filter(itemData => itemData.usedUp)}
You can use style={{ flexGrow: 0 }} on your FlatLists to prevent them from growing to fill the space.
However, this solution has certain drawbacks (eg. both lists scroll independently, and once the top one grows too large the bottom one will be pushed off screen).
A SectionList would be better suited for this purpose:
<View style={styles.tasksListContainer}>
<SectionList
sections={[
{ title: 'being used', data: tasksToShow.filter(el => el.usedUp)},
{ title: 'not being used', data: tasksToShow.filter(el => !el.usedUp)}
]}
renderItem={({ item }) => {
return item.usedUp
? <TaskIsBeingUsed itemData={itemData}/>
: <TaskIsNotBeingUsed itemData={itemData} onTaskSelect={onTaskSelect}/>
}}
/>
</View>

react-native-snap-carousel takes a lot of time to render photos

I am using a react-native-snap-carousel to render a photo gallery. I noticed that first entrance to the gallery takes a lot of time to render photos, especially if there are several photos.
const renderItem = ( photo) => {
console.log(photo); //<- it shows up quickly in the console, but the photo is not visible for a long time
return (
<View style={styles.imgContainer}>
<Image source={{ uri: photo.item.uri }} style={styles.img} />
</View>
)};
return (<Carousel
ref={carouselRef}
data={props.photos}
renderItem={renderItem}
sliderWidth={sliderWidth}
itemWidth={itemWidth}
activeSlideAlignment={'center'}
onSnapToItem={index => setActiveSlide(index)}
/>)
What could be the reason for this behavior?
What can I do with this?

ReactNative ScrollToIndex too slow

im using react native to create an app for a legal document. i need the document to be scrollable. i rendered it using VirtualizedList.
thing is when i try to use scrollToIndex(index: 'something') performance is too slow.
my list contains about 4000 rendered items (each being about a paragraph long).
is there any way to make this run smoother?
export default function App() {
const scroller = useRef();
return (
<SafeAreaView>
<View style={styles.upperContainer}>
<CustomButton
onPress={() => {
scroller.current.scrollToIndex({ index: 1547 });
}}
/>
</View>
<View style={styles.flatContainer}>
<VirtualizedList
ref={scroller}
data={data}
renderItem={({ item }) => (
<CustomText data={item.content} type={item.type} />
)}
getItem={(data, index) => data[index]}
getItemCount={(data) => data.length}
keyExtractor={(item) => item.number.toString()}
initialNumToRender={4000}
onScrollToIndexFailed={() => {
alert('error');
}}
/>
</View>
</SafeAreaView>
);
}
This question is similar to these ones and maybe you can reference some of the answers and see what works for your case. Basically, you need a pure component to make this work.
Link - Flatlist performance slow
Link - VirtualizedList: You have a large list that is slow to update

Prevent FlatList scrolling when new items are added

I have inverted vertical FlatList in my chat app, which shows newest message in bottom and oldest message in top (likes all other chat applications)
The problem is when I want to add new messages to bottom of my list, FlatList automatically jump to bottom-end of the list!
All I need is to prevent scrolling in this situation
Here is my FlatList:
<FlatList
inverted
style={{flex: 1}}
data={this.state.data}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
/>
And here is the code to add newest messages to list
const data = [ ...newMessages, ...this.state.data ];
this.setState({ data });
Your case look simple but you are adding new message at top then reverse it to bottom last position using inverted flag
Could remove inverted flag and add new item at last simply const data = [...this.state.data, ...newMessages];
<FlatList
style={{flex: 1}}
data={this.state.data}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
/>
const data = [...this.state.data, ...newMessages];
this.setState({ data });
I hope this will work
Put this in the view
<FlatList
data={this.state.data}
ref={ref => {
this.flatListRef = ref;
}}
initialScrollIndex={0}
keyExtractor={item => item.id}
extraData={this.state.refresh}
renderItem={({item, index}) => {
// animation={animation}
return (
<ListItem
inAnimation={inAnimation}
outAnimation={outAnimation}
duration={duration}
easing={easing}
isDeleted={item._isDeleted}
id={item.id}
item={item}
/>
);
}}
`/>`
Run this in a function
this.flatListRef.scrollToIndex({
animated: true,
index: nextProps.indexScroll})
});
You should use a workaround to achieve this. If you check the documentation for FlatList (which extends the props of ScrollView), you'll see that all you need to do is set the scrollEnabled prop to false to disable scrolling. How and where you choose to do this will be up to you since you didn't really post a lot of code. A simple way to handle this would be to use state:
<FlatList
...
scrollEnabled={this.state.scrollEnabled}
/>
In your case you could change the state when the new data is being loaded and change it back when it is rendered.
There is an open issue on Github about this case.

flatlist pagination make app really slow on android

i am using a flat list for rendering data from server but the problem i have is when i render lots of data my app become too much slow
<FlatList
data={this.state.product}
numColumns={2}
inverted
renderItem={({item}) =>
<TouchableOpacity style={styles.homeGride}>
<View style={styles.offer}>
<Text style={styles.offerText}>{item.offer}%</Text>
</View>
<ImageBackground style={styles.homeImage} source={{uri:`${item.img}`}}>
</ImageBackground>
<Text style={styles.homeProductText}>{item.title}</Text>
<View style={{flexDirection:"row-reverse"}}>
<Text style={{flex:1,fontFamily:"FaNum"}}>{item.price}</Text>
<Text style={{flex:1,fontFamily:"FaNum"}}>{item.new_price}</Text>
</View>
<Button small danger>
<Text style={{padding:5}}>خرید</Text>
</Button>
</TouchableOpacity>
}
keyExtractor={({id}, index) => id}
/>
you should consider using onEndReached attribute of FlatList.
first define a page state
this.setState({page:1});
when fetching data from server send page parms to chunk the data
for Ex. in laravel server side framework do this :
$data = Data::where("sth","sth")->paginate(10,'page');
now in your react native application :
<FlatList
data={this.state.product}
numColumns={2}
inverted
onEndReached={this.handleLoadMore}
onEndThreshold={10}
renderItem={({item}) =>
..sth..
}
keyExtractor={({id}, index) => id}
/>
now in handleLoadMore add 1 number to page state and again fetch data
this will help you improve your speed and performance and fetch other data when they are needed !
I recommend you use the recyclerListView component
it has better performance for android devices.