web-dev-qa-db-fra.com

Problèmes de performance React-Native FlatList avec une grande liste

Mon code obtient les données Json dans un tableau et les répertorie à l'aide de FlatList. Cela ressemble à une photo de l'annuaire et à un texte d'affilée.

Voici mon code:

  renderItem = ({ item }) => 
    (
    <ListItem
      title={item.username}
      avatar={{ uri: item.photo }}
    />
    )


  render() {
    console.log(this.state.myData);
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.myData}
          renderItem={this.renderItem}
        />
      </View>
    );
  }

Cela fonctionne et je reçois la sortie, mais la performance est lente. Le rendu prend environ 10 secondes, ce qui est gênant pour l'utilisateur. Que dois-je faire pour le rendre plus rapide?

5
bucsy

Voici quelques améliorations que vous pouvez faire pour optimiser votre liste à plat:

  1. Pagination
    • Vous pouvez paginer vos données dans votre backend et les récupérer lorsque votre parchemin se rapproche de la fin. onEndReached et onEndReachedThreshold peuvent vous aider.
  2. Mettez à jour votre version de React Native vers 49 ou plus récente.
    • La fibre 16 offre une incroyable amélioration des performances, ce qui rend tout plus rapide et plus fluide
  3. Utilisez PureComponent pour l'élément de rendu
    • PureComponent améliore le rendu et l'utilisation de la mémoire de votre composant. Créer des éléments de rendu purs vous permet de bénéficier de meilleures performances.
  4. Définir getItemLayout prop
    • Cela améliore le rendu des éléments puisque React connaîtra auparavant sa définition de mise en page.

J'espère que ça aide

2
soutot

Cette réponse est devenue un post plus grand et plus complet sur github


Si vous suivez ce fil , vous verrez que l'équipe de react est déjà consciente de ce problème de performances.

Il n’ya pas de solution miracle à ce problème, vous devez considérer les compromis de chaque approche et ce que vous pensez être une bonne expérience pour votre public. Mais heureusement, il existe plusieurs modifications que vous pouvez essayer d’améliorer FlatList.


Termes et significations

Beaucoup de termes utilisés (sur docs ou certains problèmes) ont été source de confusion pour moi au début. Éloignons cela dès le début.

  • VirtualizedList est le composant derrière FlatList et est l'implémentation de React Native du concept ' virtual list '.

  • Performance , dans ce contexte, implique une expérience de défilement régulier (et non agitée) (et de navigation dans ou hors de votre liste).

  • Consommation de mémoire , dans ce contexte, est la quantité d'informations stockées dans votre liste qui sont stockées en mémoire, ce qui pourrait entraîner un blocage de l'application.
  • Zones vides signifie que VirtualizedList ne peut pas restituer vos éléments assez rapidement. Vous entrez donc dans une partie de votre liste avec des composants non rendus.
  • Fenêtre ici, ce n’est pas votre fenêtre de visualisation, mais plutôt la taille de la zone dans laquelle les éléments doivent être rendus.

Les accessoires

Une façon d'améliorer votre FlatList consiste à modifier ses accessoires. Voici une liste des accessoires qui peuvent vous aider avec ça.

removeClippedSubviews

Vous pouvez définir la propriété removeClippedSubviews sur true, qui démonte les composants en dehors de la fenêtre.

Win: Ceci est très convivial en mémoire, car vous aurez toujours une petite liste rendue.

Compromis: Sachez que cette implémentation peut comporter des bogues, tels que du contenu manquant si vous l’utilisez sur un composant qui ne se démontera pas (tel qu’une route de navigation). soyez moins performant, avec des animations de défilement saccadées pour les grandes listes avec des éléments complexes sur des appareils pas très bons, car cela fait des quantités folles de calculs par défilement.

maxToRenderPerBatch

Vous pouvez définir le maxToRenderPerBatch={number}, qui est un prop VirtualizedList qui peut être passé directement à FlatList. Avec cela, vous pouvez contrôler la quantité d'éléments rendus par lot, qui est la prochaine tranche d'éléments rendus sur chaque défilement.

Win: Régler un nombre plus grand signifie moins de zones vides visuelles lors du défilement (meilleur est le taux de remplissage).

Compromis: Plus d'éléments par lot signifie moins de performances JavaScript, ce qui signifie moins de réactivité (cliquer sur un élément et ouvrir les détails). Si vous avez une liste statique et non interactive, cela pourrait être la voie à suivre.

initialNumToRender

Vous pouvez définir le initialNumToRender={number}. Cela signifie la quantité initiale d'éléments à rendre.

Win: Vous pouvez définir cette valeur sur le nombre précis d'éléments pouvant couvrir l'écran pour chaque périphérique. Cela peut améliorer considérablement les performances lors du rendu du composant de liste.

Compromis: Il est fort probable que vous voyiez des zones vides lorsque vous définissez une valeur initialNumToRender basse.

la taille de la fenêtre

Vous pouvez définir le windowSize={number}. Le nombre transmis ici est une unité de mesure où 1 correspond à la hauteur de votre fenêtre. La valeur par défaut est 21, soit 10 fenêtres au-dessus, 10 au-dessous et une entre les deux.

Win: Si vous êtes principalement préoccupé par les performances, vous pouvez définir une plus grande variable windowSize afin que votre liste fonctionne correctement et avec moins d'espace. Si vous êtes principalement préoccupé par la consommation de mémoire, vous pouvez définir une windowSize inférieure afin que votre liste de rendu soit plus petite.

Compromis: Pour une windowSize plus grande, vous aurez une plus grande consommation de mémoire. Pour une valeur windowSize inférieure, les performances seront plus faibles et les zones vierges plus visibles.

legacyImplementation

Cet accessoire , lorsque la valeur est vraie, faites que votre FlatList repose sur la plus ancienne ListView au lieu de VirtualizedList.

Win: Cela améliorera définitivement votre liste, car elle supprime la virtualisation et restitue tous vos éléments en même temps.

Compromis: Votre consommation de mémoire dépasse le plafond et il y a de bonnes chances qu'une grande liste (plus de 100) contenant des éléments complexes écrase votre application. Il déclenche également un avertissement indiquant que les modifications ci-dessus sont apportées. ne fonctionnera pas, car vous êtes maintenant sur une liste.

désactiver la virtualisation

Vous verrez des gens recommander l'utilisation de cet accessoire sur certaines questions. Mais ceci est obsolète maintenant . Ceci faisait autre chose comme legacyImplementation.


Articles de liste

Il existe également des stratégies gagnant-gagnant impliquant les éléments de votre liste. Ils sont souvent gérés par VirtualizedList, ils doivent donc être rapides.

Utiliser des composants simples

Plus vos composants sont complexes, plus leur rendu sera lent. Essayez d'éviter beaucoup de logique et d'imbrication dans les éléments de votre liste. Si vous réutilisez beaucoup ce composant d'élément de liste dans votre application, créez un doublon uniquement pour vos grandes listes et créez-les avec le moins de logique possible et le moins possible d'imbrication.

Utiliser des composants légers

Plus vos composants sont lourds, plus ils sont lents. Évitez les images lourdes (utilisez une version recadrée pour les éléments de la liste, aussi petite que possible). Parlez à votre équipe de conception et utilisez le moins possible d’effets, d’interactions et d’informations dans votre liste. Enregistrez-les dans les détails de votre article.

Utilisez shouldComponentUpdate

Implémentez la vérification de la mise à jour de vos composants. PureComponent de React est principalement destiné aux personnes qui n'ont pas le temps de réfléchir. Si vous lisez ceci, vous avez le temps, alors créez les règles les plus strictes pour vos composants d'élément de liste. Si votre liste est assez simple, vous pouvez même utiliser

shouldComponentUpdate() {
  return false
}
12
Filipe Merker