I am new to React Native, I've created an Instagram Clone with customizations, but there got some issues.
When the like button is Pressed, FlatList is taking 2 Seconds to re-render. So I tried into Flipkart's RecyclerView Package, that is too taking 400-600 ms. I've came to know that Instagram and Facebook are built at React Native, but they don't take this much time on like. I guess something is wrong in my code.
I got Recycler View package from here
In those screens without any List, there is too an issue of slow re-rendering.
I've found that React Navigations's
Material Top navigation is working absolutely fine on swipe, but on button click, it is taking 2-4 Seconds.
import React, { useEffect, useState, useRef } from 'react';
import { SafeAreaView, Pressable, AppRegistry, Text, View, Image, TouchableOpacity, StyleSheet, ImageBackground, ActivityIndicator, Platform } from 'react-native';
import { Pranah } from '../pranah/cust';
import { colors } from '../pranah/colors';
import { uni } from '../css/uni';
import axios from 'axios';
import base64 from 'react-native-base64';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { DataProvider, LayoutProvider, RecyclerListView } from 'recyclerlistview';
import { UserHead } from './tminc/userhead';
import { AntDesign, FontAwesome5, Feather } from '@expo/vector-icons';
import { design } from './tminc/design';
import { WebBasedNavigation } from './tminc/widenav'
const style = StyleSheet.create({
web: {
width: uni.dev("100%", "100%", "40%"),
height: uni.dev("100%", "100%", uni.height - 50),
marginLeft: uni.dev(0, 0, 10 / 100 * uni.width)
}
});
const postDesign = {
width: uni.dev(95 / 100 * uni.width, 95 / 100 * uni.width, 35 / 100 * uni.width),
height: uni.dev(95 / 100 * uni.width, 95 / 100 * uni.width, 35 / 100 * uni.width),
backgroundColor: "#ededed",
borderRadius: 10,
}
const iconDynamicSizing = 25;
const iconDesign = StyleSheet.create({
icon: {
margin: 10
}
});
//POST PART IN PARTS
//USER HEAD
function ListHead(txt) {
return (
<>
<Text
style={{
fontSize: 35,
fontWeight: "bold",
margin: 20
}}
>{txt.txt}</Text>
</>
)
}
function MediaCont(obj) {
return (
<View
style={design.media}
>
<Image
source={{ uri: obj.url }}
defaultSource={{ uri: obj.url }}
style={postDesign}
/>
<View
style={design.mediaSnap}
>
<Text style={design.mediaCap}>{obj.caption.length > 20 ? `${obj.caption.substring(0, 20)}...` : obj.caption}</Text>
</View>
</View>
);
}
function TextCont(obj) {
return (
<View
style={design.textContParent}
>
<View
style={[postDesign, design.center]}
>
<Text
style={design.textMain}
>{obj.caption}</Text>
</View>
</View>
);
}
let layoutProvider = new LayoutProvider(
index => {
return index == 0 ? "HEAD" : "NORMAL";
},
(type, dim) => {
switch (type) {
case "NORMAL":
dim.height = uni.dev(uni.width + 150, uni.width + 150, 40 / 100 * uni.width + 150);
dim.width = uni.dev(uni.width, uni.width, 40 / 100 * uni.width);
break;
case "HEAD":
dim.height = 85;
dim.width = uni.dev(uni.width, uni.width, 40 / 100 * uni.width);
break;
}
}
);
function PostLikes(obj) {
let post = obj.postId;
let like = parseInt(obj.like);
let navigation = obj.screenNav;
let toprint;
if (like == 0) {
toprint = uni.lang("इसे पसंद करने वाले पहले व्यक्ति बनें", "Be first to like this.");
} else if (like == 1) {
toprint = uni.lang("एक व्यक्ति द्वारा पसंद किया गया", "Liked by one person");
} else {
like = String(like);
toprint = uni.lang(`${like} लोगो ने पसंद किया`, `${like} likes`);
}
return (
<>
<TouchableOpacity
onPress={() => {
navigation.push('LikeList', { postId: post });
}}
>
<Text
style={{
marginLeft: uni.dev(5 / 100 * uni.width, 5 / 100 * uni.width, 4 / 100 * uni.width),
fontWeight: "bold",
marginTop: 5
}}
>{toprint}</Text>
</TouchableOpacity>
</>
);
}
const headerComp = ({
title: uni.lang("सबकुछ ||", "Everything."),
type: "head"
});
export function Feed({ navigation }) {
const [List, setData] = useState([headerComp]);
const [FooterConst, setFoot] = useState(true);
const [start, setStart] = useState(0);
// navigation.setOptions({ tabBarVisible: false });
let dataProvider = new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows(List);
function fetchMore() {
AsyncStorage.getItem("mail")
.then((val) => {
let mail = val;
AsyncStorage.getItem("pass")
.then((value) => {
let pass = value;
// CONNECTING TO SERVER
axios({
method: 'post',
url: uni.bind('feed'),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: uni.string({
mail: mail,
pass: base64.encode(pass),
start: start
})
})
.then((resp) => {
if (resp.status == 200) {
let page = resp.data;
/*
SERVER RETURNS
nomore | followernull | error | invalid | {json data}
*/
if (uni.logic(page) === "error") {
uni.Error();
} else if (uni.logic(page) === "followernull" || uni.logic(page) === "nomore") {
//SET FOOTER
setFoot(false);
} else if (uni.logic(page) === "invalid") {
//SIGNOUT
uni.signOut(navigation);
} else {
setStart(start + 20);
setData(
[
...List,
...page
]
);
}
} else {
uni.Error();
}
})
.catch((e) => {
uni.Error();
});
})
.catch((e) => { uni.signOut(navigation) })
})
.catch(() => { uni.signOut(navigation) })
}
function PostAction(obj) {
let index = obj.in;
function addRemoveLike() {
let temp = List;
temp[index].liked = temp[index].liked === "true" ? "false" : "true";
// console.warn(temp[index]);
setData([...temp]);
//SAVING LIKE ON SERVER
AsyncStorage.getItem("mail")
.then((val) => {
let mail = val;
AsyncStorage.getItem("pass")
.then((value) => {
let pass = value;
// CONNECTING TO SERVER
axios({
method: 'post',
url: uni.bind('like'),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: uni.string({
mail: mail,
pass: base64.encode(pass),
post: String(obj.id)
})
})
.then((resp) => {
if (resp.status == 200) {
let page = resp.data;
/*
SERVER RETURNS
true | error | invalid
*/
if (uni.logic(page) === "error") {
uni.Error();
} else if (uni.logic(page) === "invalid") {
uni.signOut(navigation);
}
} else {
uni.Error();
}
})
.catch((e) => { uni.Error() });
})
.catch((e) => { uni.signOut(navigation) })
})
.catch(() => { uni.signOut(navigation) })
}
return (
<>
<View
style={design.postActionParent}
>
<TouchableOpacity
onPress={() => {
// console.warn(likeRef.current);
// console.warn(likeRef.current);
addRemoveLike();
}}
><AntDesign name={obj.liked === "true" ? "heart" : "hearto"} size={iconDynamicSizing} color="black" style={iconDesign.icon} /></TouchableOpacity>
<TouchableOpacity onPress={() => {
navigation.push('Comment', { postId: obj.id });
}}><FontAwesome5 name="comment" size={iconDynamicSizing} color="black" style={iconDesign.icon} /></TouchableOpacity>
<TouchableOpacity><Feather name="send" size={iconDynamicSizing} color="black" style={iconDesign.icon} /></TouchableOpacity>
<TouchableOpacity><AntDesign name="retweet" size={iconDynamicSizing} color="black" style={iconDesign.icon} /></TouchableOpacity>
</View>
<View
style={design.underLinePrnt}
>
<View style={design.underline}></View>
</View>
</>
);
}
function TextPost(params) {
let item = params.data;
let index = params.in;
return (
<>
<UserHead dp={item.dp} name={item.name} user={item.username} />
<Pressable onLongPress={() => { alert('null') }}><TextCont caption={item.caption} /></Pressable>
<PostLikes like={item.fav} postId={item.id} screenNav={navigation} />
<PostAction liked={item.liked} in={index} id={item.id} />
</>
);
}
function MediaPost(params) {
let item = params.data;
let index = params.in;
return (
<>
<UserHead dp={item.dp} name={item.name} user={item.username} />
<MediaCont url={item.url} caption={item.caption} />
<PostLikes like={item.fav} postId={item.id} screenNav={navigation} />
<PostAction liked={item.liked} in={index} id={item.id} />
</>
);
}
function ListItem(type, data, index) {
let item = data;
return item.type === "head" ? <ListHead txt={item.title} /> : item.type === "text" ? <TextPost data={item} in={index} /> : <MediaPost data={item} in={index} />;
}
useEffect(function () {
// let tmp = List.push(json);
// setData([
// ...List,
// ...json
// ]);
navigation.setOptions({ tabBarVisible: uni.isPC() == true ? false : true })
fetchMore();
}, []);
function footerComp() {
return FooterConst == true ? (
<>
<ActivityIndicator size={"large"} color={colors.primary} />
<Pranah.br height={20} />
</>) : (
<>
<Text
style={{
textAlign: "center",
width: "100%",
fontSize: 20,
fontWeight: "bold",
paddingBottom: 13
}}
>{uni.lang("सूची का अंत", "End of Posts")}</Text>
</>
);
}
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "#FFFFFF" }}>
<ImageBackground
style={{
width: "100%",
height: "100%"
}}
source={require('../assets/background_mobile.png')}
>
<Pranah.stb />
<Pranah.pranahHead nav={navigation} />
<View
style={{ width: "100%", height: "100%", flexDirection: "row" }}
>
<View
style={style.web}
>
<RecyclerListView
dataProvider={dataProvider}
rowRenderer={ListItem}
layoutProvider={layoutProvider}
extendedState={{ List }}
renderFooter={footerComp}
onEndReached={fetchMore}
/>
</View>
<WebBasedNavigation navigation={navigation} />
</View>
</ImageBackground>
</SafeAreaView>
);
}
There were lags in iOS and Web too but those were acceptable.
I know, I've done very wrong with AsyncStorage, please tell me a short way to do that too.
Thanks in advance.
In your case, I don't know why you are using come another package when react-native contains a built-in component called as FlaatList which is backed by virtualised rendering.
Make this changes
rowRenderer={() => ListItem()}
renderFooter={() => footerComp()}
Check the () =>
arrow function this will assign the method only once on the initial render. You need to provide a https://reactnative.dev/docs/flatlist#keyextractor
prop to create a unique ID for all the rendered items (will be used when you want to do some action like remove element or update).
With this simple change, you should see a lot of performance improvement for the initial render & for each re-render.
Do the same for the props that accept a function as a param.
IDK why are you storing the value on async storage they should be store in a local variable like the useState
hook. Keep an eye on the API call if you do frequent API calls or on each re-render surely it will reduce the app performnce.
React & React Native are fast by default but developers use a lot of anti-pattern code and make the application slow and complain RN is slow.
Here you can find some of the common things which cause performance issues in react native.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.