L'application mobile React Native fonctionne très lentement à chaque clic . J'utilise react native v0.40.0
et suivants sont les dépendances de mon projet.
{
"analytics-react-native": "^1.1.0",
"apisauce": "^0.7.0",
"babel-preset-es2015": "^6.18.0",
"es6-promise": "^4.0.5",
"flow-bin": "^0.36.0",
"geolib": "^2.0.22",
"immutable": "^3.8.1",
"intl": "^1.2.5",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.17.4",
"lodash.range": "^3.2.0",
"prop-types": "^15.5.10",
"raven-js": "^3.13.1",
"react": "^15.4.2",
"react-native": "^0.40.0",
"react-native-Apple-healthkit-rn0.40": "^0.3.2",
"react-native-blur": "^2.0.0",
"react-native-button": "^1.7.1",
"react-native-checkbox": "^2.0.0",
"react-native-code-Push": "^1.17.3-beta",
"react-native-datepicker": "^1.4.4",
"react-native-device-info": "^0.10.1",
"react-native-easy-toast": "^1.0.6",
"react-native-fbsdk": "^0.5.0",
"react-native-geocoder": "^0.4.5",
"react-native-gifted-chat": "^0.1.3",
"react-native-global-props": "^1.1.1",
"react-native-image-crop-picker": "^0.15.1",
"react-native-image-picker": "^0.25.1",
"react-native-image-slider": "^1.1.5",
"react-native-keyboard-aware-scroll-view": "^0.2.7",
"react-native-maps": "0.15.2",
"react-native-modal-dropdown": "^0.4.4",
"react-native-popup-menu": "^0.7.2",
"react-native-Push-notification": "^2.2.1",
"react-native-radio-buttons": "^0.14.0",
"react-native-router-flux": "3.38.0",
"react-native-segmented-Android": "^1.0.4",
"react-native-snap-carousel": "2.1.4",
"react-native-stars": "^1.1.0",
"react-native-swipeout": "^2.2.2",
"react-native-swiper": "^1.5.4",
"react-native-tableview-simple": "0.16.5",
"react-native-vector-icons": "^4.0.0",
"react-native-video": "^1.0.0",
"react-native-zendesk-chat": "^0.2.1",
"react-redux": "^4.4.6",
"recompose": "^0.20.2",
"redux": "^3.5.2",
"redux-thunk": "^2.0.1"
}
J'ai fait du profilage avec stacktrace dans Android studios, et j'ai trouvé que mqt_js est l'une des raisons qui prend plus de temps à chaque clic sur l'interface utilisateur. Vous pouvez vérifier le rapport stacktrace ici
Quelqu'un peut-il m'aider à résoudre ce problème de performances.?
Tout d'abord, vous devez exécuter votre application en dehors de [~ # ~] déboguer [~ # ~] . Sur Android cela se fait en changeant la méthode MainApplication
:
@Override
public boolean getUseDeveloperSupport() {
return false; // BuildConfig.DEBUG;
}
et faire un bundle:
react-native bundle --platform Android --dev false --entry-file ./index.js --bundle-output ./Android/app/src/main/assets/index.Android.bundle --assets-dest ./Android/app/src/main/res/ --sourcemap-output ./Android/app/src/main/assets/index.Android.map
Quant au code, voici quelques conseils pour l'optimisation react-native:
response.json()
ou JSON.stringify
) Bloquent le thread js, donc toutes les animations et tous les gestionnaires JS (tels que onScroll
et onPress
, et de cours render
méthode) en souffrent. Essayez de charger uniquement ce que vous devez montrer.useNativeDriver: true
) Là où c'est possible, et essayez de ne pas utiliser onScroll
.render
et essayez de rendre l'appel de ces méthodes aussi rare que possible. Il est appelé lorsque les accessoires ou l'état du composant changent.PureComponent
fonctionne et essayez de l'utiliser si nécessaire. Mais gardez à l'esprit qu'il peut également ralentir l'application si elle n'est pas utilisée correctement.StyleSheet
pour les styles, il les encapsule et les remplace par style id (entier).Mauvais:
// style object is created on every render
render() {
return <View style={{flex:1}}/>
}
Bien:
render() {
<View style={styles.flex}/>
}
// style is created once
const styles = StyleSheet.create({
flex: { flex: 1 }
});
Mauvais:
// onPress handler is created on every render
render() {
<TouchableOpacity onPress={() => this.props.navigator.navigate('SignIn')}/>
}
Bien:
render() {
<TouchableOpacity onPress={this.onPressSignIn}/>
}
// onPressSignIn is created once
onPressSignIn = () => {
this.props.navigator.navigate('SignIn');
}
Object
et Set
au lieu de Array
là où c'est possible. Utilisez la pagination lorsque vous devez charger de grandes quantités de données à partir du serveur/base de données, laisser le tri et d'autres calculs lourds pour le serveur.Par exemple, si vous avez souvent besoin d'obtenir des objets par id, il est préférable d'utiliser:
let items = {
"123": { id: "123", ... },
"224": { id: "224", ... }
};
let item = items["123"];
au lieu du tableau habituel:
let items = [
0: { id: "123", ... },
1: { id: "224", ... }
];
let item = items.find(x => x.id === "123");
Ceci est une question très très large et basée sur l'opinion , mais je vais essayez de mettre en évidence le most common points
et des suggestions basées sur le profiler
que vous avez répertorié.
En regardant votre trace de pile, le principal problème réside dans le UI Thread
à l'intérieur du nom de votre package, c'est-à-dire com.fitspot.app.debug
.
Comme mentionné ici .
afin d'afficher un cadre, tout notre travail d'interface utilisateur doit être effectué à la fin de cette période de 16 ms.
Une fois l'intervalle limite défini sur 16ms
, vous pouvez voir que le mqt_js
ou la JS Thread
prend beaucoup plus de temps que 16ms
pour un cycle, ce qui signifie que votre JS Thread
fonctionne en permanence.
Dans le profiler
actuel, il est difficile de savoir quels processus sont exécutés dans votre JS Thread
, il est donc clair que le problème réside principalement dans votre JS Code
et non le UI Thread
.
Il existe plusieurs façons de rendre le react-native
application plus rapide qui est bien documentée dans ce page . Voici un Gist de base à la même chose.
dev=true
, vous pouvez les désactiver dans l'application pour de meilleures performances.Supprimez tous les console.log
instructions de votre application, car cela provoque un bottleneck
sur le thread JS. Vous pouvez utiliser ce plugin pour supprimer tous les console*
instructions comme mentionné ici , dans vos fichiers .babelrc comme
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
Vous devez componentize
la structure de votre projet et utiliser Pure Components
, pour utiliser uniquement props
et state
, utilisez immutable data structures
pour des comparaisons plus rapides.
Pour le slower navigation transitions
, vous voudrez peut-être vérifier le navigation library
code, car la plupart du temps, ils ont un timeout
pour default transitions
. Comme solution de contournement, vous pouvez envisager de créer votre propre transitioner
.
Si vous utilisez Animations
dans votre base de code, vous pouvez envisager de définir nativeDriver=true
, ce qui réduirait la charge sur votre JS thread
. Voici un bien expliqué exemple .
Vous pouvez également vouloir vérifier le profilage , pour vérifier le JS Thead
et le Main Thread
opérations, bien expliquées sur cette page.
D'autres choses incluent, pas requiring/importing
le module, qui n'est pas nécessaire, n'important que classes
requis, et non le whole component
.
De plus, vous n'avez pas besoin de external libraries
faire simple UI components
, car leurs performances sont beaucoup plus lentes que les éléments natifs de react-native
. Vous pouvez envisager d'utiliser styled-components
pour composant votre UI
Utilisez Flatlist sur Scrollview:
initialNumToRender={number}
prop à Flatlist, car il n'affichera que les composants visibles à l'écran et détachera les autres composantsUtilisez PureComponent dans Flatlist renderItem (dans votre cas, il s'agira de chaque carte), afin qu'ils ne s'affichent que lorsque leurs accessoires sont modifiés.
Vérifiez si votre composant est restitué encore et encore afin de tester la console de mise soit dans render () ou dans ComponentWillRecieveProps et si cela se produit, utilisez ShouldComponentUpdate.
Supprimez console.log de render () et ComponentWillRecieveProps.
Apportez ces modifications et vous voyez que vos performances sont bien meilleures qu'auparavant.
Plusieurs raisons peuvent ralentir l'application native de react. Je suggère les points clés suivants qui peuvent aider:
dumb components
plus de class components
la mesure du possible.redux
, c'est un puissant outil de gestion d'état qui peut vous fournir le meilleur code, s'il est correctement implémenté.react-monocole
et appr
. Guide de react-monocole .Si mqt_js
est la principale cause de problème de performances, ce qui signifie qu'à chaque clic, le thread JS de votre application a trop de choses à faire à la fois. La communication entre la logique métier JS et le domaine natif sous-jacent se fait de manière asynchrone, plus le nombre d'actions doit être terminé côté JS lorsqu'un bouton est enfoncé, plus l'application sera lente.
Réponse donné par Pritish Vaidya frappe déjà le clou sur la tête. Je veux juste inclure 1 point de plus sur l'utilisation de redux
dans votre application. Si le flux de données de votre application se fait principalement à l'aide de redux
, vous pouvez vérifier les éléments suivants:
S'il y a trop d'actions redux se produisant à chaque événement de clic, essayez de supprimer celles inutiles ou de prioriser les actions déclenchant d'abord des animations importantes, puis de déclencher d'autres actions une fois que les nouveaux composants RN ont terminé le rendu. Vous pouvez voir quelles actions sont des actions à col bas par redux-logger
.
Divisez les composants écoutant le magasin de redux en plus petits, chacun écoutant une partie différente du magasin. Donc, si le magasin de redux est mis à jour, seul un petit groupe de composants doit être rendu à la place de tout.
Utilisez des sélecteurs mémorisés pour traiter les données fréquemment mises à jour. resélectionnez peut vous aider dans ce cas.