
React-Native-Best Practice est une meilleure pratique native réactive et un package, qui fournit des techniques pour augmenter les performances ainsi que les services publics pour augmenter les performances de l'application
Vous devriez utiliser pourquoi-tu-you qui vous informez des redesseurs potentiellement évitables.
import React from 'react' ;
const useWDYR = __DEV__ ;
if ( useWDYR ) {
const whyDidYouRender = require ( '@welldone-software/why-did-you-render' ) ;
whyDidYouRender ( React , {
// Enable tracking in all pure components by default
trackAllPureComponents : true ,
trackHooks : true ,
include : [
// Uncomment to enable tracking in all components. Must also uncomment /^Screen/ in exclude.
// /.*/,
// Uncomment to enable tracking by displayName, e.g.:
// /^Components/,
] ,
exclude : [
// Uncomment to enable tracking in all components
// /^Components/,
] ,
} ) ;
} Importez le code de fichier ci-dessus dans votre application Root index.js
Vous permet de relancer un composant lorsque ses accessoires sont inchangés.
Il est important de mémoriser des calculs lourds ainsi que des tableaux et des créations d'objets afin qu'ils ne soient pas recréés sur chaque rendu. Un rendu se produit lorsque l'état change, Redux envoie une action ou lorsque l'utilisateur se transforme en une entrée de texte (renvoyer pour chaque touche appuyant sur la touche). Vous ne voulez pas exécuter beaucoup d'opérations dans ces rendus pour des raisons très évidentes - donc pas de filtrage lourd, pas d'opérations de liste, etc.
Un composant pur (ou un composant React.memo ) ne renforce pas si ses accessoires sont à l'égalité peu profonde .
Chaque variable que vous créez dans votre fonction de rendu sera réaffectée sur chaque rendu. Bien que ce ne soit pas un problème pour les types de valeur , cela fait que les types de référence sont différents sur chaque rendu. Lorsque vous transmettez ces variables en composants purs via des accessoires, ils renforceront toujours même si les accessoires sont logiquement les mêmes. Souvent, ces variables dépassent même le pont et rendent votre application lentement.
Lorsqu'un composant pur redémarre, il compare les accessoires précédents aux accessoires et vérifies actuels s'ils sont peu profonds .
Les nombres , les chaînes et les booléens sont des types de valeur , ce qui signifie qu'ils peuvent être comparés par valeur :
const i1 = 7 ;
const i2 = 7 ;
const equal = i1 === i2 ; // trueLes objets , les tableaux et les fonctions sont des types de référence , ce qui signifie qu'ils ne peuvent pas être comparés par leur valeur logique, mais doivent être comparés par référence :
const o1 = { x : 7 } ;
const o2 = { x : 7 } ;
const equal = o1 === o2 ; // false Les comparaisons de référence comparent simplement l'adresse mémoire de la variable, donc seul o1 === o1 serait true dans l'exemple de code ci-dessus.
«Isqual
fromReact-Native-Best-Practice» pour comparer les objets par l'égalité réelle, mais ce n'est plus l'égalité peu profonde .
Si vous créez des objets dans votre fonction de rendu, ils seront recréés sur chaque rendu. Cela signifie que lorsque vous créez un objet dans le premier rendu, il n'est pas égal à l'objet dans le deuxième rendu. Pour cette raison même, la mémorisation existe.
useMemo pour mémoriser des tableaux et des objets qui garderont leur égalité de référence (et ne seront pas recréés sur chaque rendu) tant que les dépendances (deuxième argument) restent les mêmes. Utilisez également useMemo pour mettre en cache des calculs lourds, tels que les opérations de tableau, le filtrage, etc.useCallback pour mémoriser une fonction.useDeepEffect , useDeepCallback , useDeepImperativeHandle et useDeepLayoutEffect à partir de import {useDeepEffect, ...} from 'react-native-best-practice'En général, les composants de la fonction peuvent être optimisés plus facilement en raison du concept de crochets. Vous pouvez cependant appliquer des techniques similaires pour les composants de classe, sachez simplement que cela entraînera beaucoup plus de code.
Bien que les animations et les tâches à forte performance soient planifiées sur des threads natifs, toute votre logique métier fonctionne sur un seul fil JavaScript, alors assurez-vous que vous faites le moins de travail possible. Faire trop de travail sur le fil JavaScript peut être comparé à un ping élevé dans un jeu vidéo - vous pouvez toujours regarder en douceur, mais vous ne pouvez pas vraiment jouer au jeu parce que chaque interaction prend trop de temps.
Les composants natifs ( <View> , <Text> , <Image> , <Blurhash> , ...) doivent transmettre des accessoires aux natifs via le pont. Ils peuvent être mémorisés, donc React compare les accessoires pour l'égalité peu profonde et ne les passe sur le pont que s'ils sont différents des accessoires du dernier rendu. Si vous ne mémorisiez pas correctement, vous pourriez passer des accessoires sur le pont pour chaque rendu, ce qui rend le pont très occupé. Voir l'exemple des styles - Les styles seront envoyés sur le pont à chaque rendez-vous!
Voici quelques exemples pour vous aider à éviter de faire trop de travail sur votre fil JavaScript:
return < View style = { [ styles . container , { backgroundColor : 'red' } ] } /> ; const style = useMemo ( ( ) => [ styles . container , { backgroundColor : 'red' } ] , [ ] ) ;
return < View style = { style } /> ;useAnimatedStyle , car ceux-ci doivent être dynamiques. L'utilisation filter , map ou d'autres opérations de tableau dans les rendus exécutera à nouveau l'ensemble de l'opération pour chaque rendu.
return (
< Text > { users . filter ( ( u ) => u . status === 'online' ) . length } users online </ Text >
) ; const onlineCount = useMemo (
( ) => users . filter ( ( u ) => u . status === 'online' ) . length ,
[ users ]
) ;
return < Text > { onlineCount } users online </ Text > ; Vous pouvez également l'appliquer pour rendre plusieurs vues de réaction avec .map . Ceux-ci peuvent également être mémorisés avec useMemo .
return < View onLayout = { ( layout ) => console . log ( layout ) } /> ; const onLayout = useCallback ( ( layout ) => {
console . log ( layout ) ;
} , [ ] ) ;
return < View onLayout = { onLayout } /> ; Assurez-vous de penser également aux autres appels du rendu, par exemple, useSelector , useComponentDidAppear - enveloppez le rappel là-bas aussi!
function MyComponent ( props ) {
return < PressableOpacity onPress = { ( ) => props . logoutUser ( ) } /> ;
} function MyComponent ( props ) {
return < PressableOpacity onPress = { props . logoutUser } /> ;
} function MyComponent ( props ) {
return (
< RecyclerListView scrollViewProps = { { horizontal : props . isHorizontal } } />
) ;
} function MyComponent ( props ) {
const scrollViewProps = useMemo (
( ) => ( {
horizontal : props . isHorizontal ,
} ) ,
[ props . isHorizontal ]
) ;
return < RecyclerListView scrollViewProps = { scrollViewProps } /> ;
} function MyComponent ( ) {
return < RecyclerListView scrollViewProps = { { horizontal : true } } /> ;
} const SCROLL_VIEW_PROPS = { horizontal : true } ;
function MyComponent ( ) {
return < RecyclerListView scrollViewProps = { SCROLL_VIEW_PROPS } /> ;
} Cela s'applique aux objets ainsi qu'aux fonctions qui ne dépendent pas de l'état ou des accessoires du composant. Utilisez-vous toujours si vous le pouvez, car c'est encore plus efficace que useMemo et useCallback .
const [ me , setMe ] = useState ( users . find ( ( u ) => u . id === myUserId ) ) ; const [ me , setMe ] = useState ( ( ) => users . find ( ( u ) => u . id === myUserId ) ) ; Le crochet useState accepte une fonction d'initialisateur. Alors que le premier exemple ("Bad") exécute le .find sur chaque rendu, le deuxième exemple ne fait qu'une seule fois la fonction passée pour initialiser l'état.
Lors de l'écriture de nouveaux composants, je mets toujours une instruction de journal dans ma fonction de rendu pour regarder passivement la fréquence à laquelle mon composant est réécrit pendant que j'y travaille. En général, les composants devraient renforcer le moins possible, et si je vois beaucoup de journaux apparaître dans ma console, je sais que j'ai fait quelque chose de mal. C'est une bonne paction pour mettre cette fonction dans votre composant une fois que vous commencez à y travailler et le supprimer une fois fait.
function ComponentImWorkingOn ( ) {
// code
console . log ( 're-rendering ComponentImWorkingOn!' ) ;
return < View /> ;
}Vous pouvez également utiliser la bibliothèque Why-did-You-Render pour découvrir pourquoi un composant s'est rendu (modifications des accessoires, modifications d'état, ...) et éventuellement attraper des erreurs dès le début.
React.memo export const MyComponent = ( props ) => {
return ...
} const MyComponentImpl = ( props ) => {
return ...
}
export const MyComponent = React . memo ( MyComponentImpl ) ; Si votre composant rend le même résultat compte tenu des mêmes accessoires, vous pouvez l'envelopper dans un appel à React.memo(...) pour un boost de performance dans certains cas en faisant la mémoire du résultat. Cela signifie que React sautera le rendu du composant et réutilisera le dernier résultat rendu. Voir les documents officiels de React.memo et utilisez sagement React.memo(...) .
Si votre application est lente, essayez la bibliothèque React-Native-performance et son plugin Flipper pour profiler les performances de votre application dans divers aspects tels que le temps pour interactif , le temps de rendu des composants , l'exécution de script et plus encore.
N'optimisez pas prématurément. Certains exemples utilisés ici (par exemple celui useMemo ) sont très petits et ne montrent que l'idée. Un crochet comme `UseMemo est également livré avec un coût (allouant la fonction et le tableau DEPS, appelant le crochet réel et exécutant une comparaison du tableau), alors gardez à l'esprit qu'il est souvent préférable de simplement passer des objets ou des tableaux directement si le composant lui-même est optimisé. Après une certaine complexité des composants ou avec un certain graphique de dépendance, les fonctions de mémorisation peuvent être une énorme victoire de performance, mais il y a aussi des cas où cela conduit simplement à un code inutilement complexe et parfois à des performances encore pires. Toujours comparer avant et après!
npm i react-native-best-practice
Tous les arguments passants comme dans React Hooks indigènes comme
import {useDeepEffect} from 'react-native-best-practice'
useDeepEffect(()=>{
},[recreatedDeepObject])
useDeepEffect => useEffectuseDeepMemo => useMemouseDeepCallback => useCallbackuseDeepImperativeHandle => useImperativeHandleuseDeepLayoutEffect => useLayoutEffectisEqual => Vérifiera profondément IsEqualcloneDeep => clonera les objets et le tableau profondément Allumez toujours le moniteur PREF tout en développant l'application car il vous indiquera à l'interface utilisateur et à la catégorie JS, si une trame tombe, vous pouvez vérifier quel nouveau code provoque une trame et faire de votre temps vers l'interactif (TTI) bas, vous pouvez ouvrir le Dev Menu dans votre application et basculer Show Perf Monitor . 
N'utilisez jamais Flatlist, utilisez toujours Flashlist car il utilise le concept de vues de recyclage, qui ne créent et ne rendent pas un nombre limité de vues visibles à l'écran
Créez une instance de journalisation personnalisée et appliquez les emojis pour catégoriser les journaux. De cette façon, il est plus facile de repérer les lignes pertinentes dans votre console et semble plus amicale dans l'ensemble. Faites beaucoup de journalisation pour vous épargner des longues nuits de débogage à un moment ultérieur! 
Utilisez toujours la fiche native de @rectnavigation. Puisqu'il utilise des primitives d'écran natives de plate-forme, elle vaut presque toujours la peine des gains de performances sur la pile basée sur JS. 
Redux Si vous utilisez déjà redux, vous devez utiliser la reélection pour les fonctions "Selector"
React Context Si vous utilisez déjà React Context, vous devez utiliser Use-Context-Selector pour les fonctions "Selector" MÉMOISEMENT, Sinon, une valeur de contexte est modifiée, toutes les composants que UseContext se renvoient.
recommandé d'utiliser ces libs recul, Jotai Zustand pour la gestion de l'État
Si vous avez besoin de faire quelque chose dans le composant enfant de la composante parent, utilisez la réf et use Impérative Handle pour appeler les fonctions de composants enfants de la composante parent au lieu de jouer avec l'état passant dans le composant enfant
Utilisez la fourche React-Native-Buffer de @craftzdog, lorsque vous traitez avec beaucoup de tampons pour accélérer votre application. Il utilise des implémentations soutenues par C ++ exposées via JSI, qui est à peu près 4x plus rapidement que l'implémentation basée sur JS. 
Utilisez React-Native-MMKV pour stocker et récupérer de manière synchrone les données du stockage local, qui persiste même lors du prochain lancement de l'application. Par rapport à LocalStorage sur le Web, MMKV vous permet également de crypter vos données et d'avoir plusieurs instances! 
Utilisez React-Native-Blurhash pour montrer de beaux espaces réservés flous pour vos images et vidéos. Générez une courte chaîne qui représente une version floue de votre contenu ("blurhash") côté serveur et envoyez-le à côté de vos données à l'application! 
Lorsque vous présentez des nombres à l'utilisateur, vous devez les formater dans le lieu de lieu approprié (virgules, signes de devise, ..) Bien que .Tolocalestring (..) fait son travail, vous pouvez réellement construire votre propre instance NumberFormat pour améliorer les performances de ~ 2x! 
Gérez toujours les encarts de zone sûre de manière appropriée. Au lieu d'envelopper l'écran entier dans A, vous pouvez travailler avec des paddages pour créer des UIS plus propres.
Ici, nous avons dépassé contentContainerStyle={{ paddingBottom: safeAreaBottom }} au:
Lisez "C ++ moderne efficace". Même si vous n'êtes pas un développeur C ++, ce livre vous aidera à comprendre le fonctionnement de la gestion de la mémoire et le croyez ou non, cela affecte la façon dont vous pensez à React (natif). En fait, c'est le seul livre de programmation que j'ai jamais lu
Vous comprendrez pourquoi {} === {} est faux, comment fonctionne l'égalité de l'identité, comment les redireurs sont des tonnes d'allocations, comment éviter les copies et beaucoup d'autres choses sur les performances qui vous font penser un peu différente lors de l'écriture de code. Vous n'optimisez pas prématurément?
Et si vous voulez aller dans le développement C ++ avec JSI, il est encore mieux que vous lisez ce livre - C ++ n'est pas aussi indulgent que JS. Si vous créez une bibliothèque qui contient un mauvais code C ++, les utilisateurs vous détesteront pour avoir créé leur application sigabrt?
N'utilisez jamais directement le composant. Au lieu de cela, créez votre propre abstraction afin de ne pas vous répéter avec le nom de police, la taille ou les couleurs de police à chaque fois et il est plus facile de changer les propriétés à tout moment.
De plus, créez une règle Eslint pour vous avertir chaque fois que vous essayez d'utiliser au lieu de ️ 
Lorsque vous traitez avec de grands nombres, utilisez React-Native-Bignumber au lieu de l'une des bibliothèques basées sur JS. ⚡️ Il est soutenu par une pure implémentation C ++ et est ~ 330x plus rapide que Bn.js dans certaines applications (par exemple #Crypto Apps, Ethers.js, elliptique, bitcoin) 
Lorsque vous travaillez avec #Crypto / Cryptographie, utilisez React-Native-Quick-Crypto au lieu de l'une des bibliothèques basées sur JS. ⚡️ Il est soutenu par une implémentation C ++ pure et est jusqu'à 58x plus rapide que le-natif-natif ou le crypto réactif ou le crypto-rupture dans certains scénarios.
Vous pouvez utiliser la lampe de poche pour générer un score de performance pour votre application Android
Vous pouvez faire du profilage pour l'optimisation des performances.
Vous devez supprimer console.log de l'application prod comme utilisant console.log les instructions abaissent le FPS, vous pouvez supprimer Console.log en lisant ceci
Merci à Marc Rousavy et Margelo, car principalement les meilleures pratiques sont leur