Progression
0 %
0/32 étapes terminées
Intermédiaire · 9 min de lecture
FlatList sous le capot
Virtualisation, fenêtres et pièges de performance
1Définition
FlatList est un composant de liste virtualisée : il ne rend qu'une fenêtre d'éléments autour de la zone visible et recycle la mémoire à mesure qu'on défile.
2Principes fondamentaux
01
Une fenêtre de rendu
windowSize (21 par défaut, en hauteurs d'écran) détermine combien de contenu reste monté autour de la zone visible.
02
Un premier rendu court
initialNumToRender fixe le nombre d'éléments rendus au départ (10 par défaut) pour afficher vite le haut de la liste.
03
Des éléments purs
FlatList est un PureComponent : si data garde la même référence, la liste ne se re-rend pas. Pour réagir à un autre état, utilise extraData.
04
Mesurer coûte cher
Sans getItemLayout, chaque ligne doit être mesurée. Si toutes ont la même hauteur, fournis-la pour sauter directement à n'importe quel index.
3Exemples pratiques
Grille, en-tête et liste vide
1import { FlatList, View, Text, StyleSheet } from 'react-native';2 3const badges = ['Premier Touché', 'Sans faute', 'Combo ×10', 'Série 7 jours', 'Podium', 'Bâtisseur'].map((titre, i) => ({ id: String(i), titre }));4 5export default function App() {6 return (7 <FlatList8 data={badges}9 numColumns={2}10 keyExtractor={(item) => item.id}11 columnWrapperStyle={{ gap: 12 }}12 contentContainerStyle={{ padding: 16, gap: 12 }}13 ListHeaderComponent={<Text style={styles.titre}>Mes badges</Text>}14 ListEmptyComponent={<Text>Aucun badge pour l'instant.</Text>}15 renderItem={({ item }) => (16 <View style={styles.badge}>17 <Text style={styles.nom}>{item.titre}</Text>18 </View>19 )}20 />21 );22}23 24const styles = StyleSheet.create({25 titre: { fontSize: 28, fontWeight: '800', marginBottom: 4 },26 badge: { flex: 1, height: 110, borderRadius: 18, backgroundColor: '#fbe9a6', justifyContent: 'flex-end', padding: 14, borderWidth: 2, borderColor: '#171718' },27 nom: { fontWeight: '800' },28});numColumns et columnWrapperStyle pour la grille, et des composants d'en-tête et de liste vide intégrés.
Hauteur fixe : getItemLayout
1const HAUTEUR = 72;2 3<FlatList4 data={contacts}5 keyExtractor={(c) => c.id}6 renderItem={renderContact}7 getItemLayout={(_, index) => ({ length: HAUTEUR, offset: HAUTEUR * index, index })}8/>La liste connaît la position de chaque ligne sans la mesurer : scrollToIndex devient instantané.
4Erreurs courantes
Une liste qui ne se met pas à jour
À éviter
<FlatList data={items} renderItem={({ item }) => <Ligne selectionne={item.id === selection} />} />À faire
<FlatList data={items} extraData={selection} renderItem={({ item }) => <Ligne selectionne={item.id === selection} />} />Pourquoi : Le rendu dépend de selection, que FlatList ne surveille pas. extraData lui signale de se re-rendre.
FlatList dans un ScrollView
À éviter
<ScrollView> <Profil /> <FlatList data={posts} … /></ScrollView>À faire
<FlatList data={posts} ListHeaderComponent={<Profil />} …/>Pourquoi : Dans un ScrollView de même direction, la virtualisation est désactivée : tout est rendu.
Des keys instables
À éviter
keyExtractor={() => Math.random().toString()}À faire
keyExtractor={(item) => item.id}Pourquoi : Une key qui change à chaque rendu recrée chaque ligne à chaque fois.
5Subtilités à connaître
- ◆
onEndReachedThreshold(0,5 par défaut) règle à quelle distance de la fin déclencheronEndReached. - ◆
SectionListgère des listes groupées avec en-têtes de section. - ◆Pour les très longues listes complexes,
@shopify/flash-listrecycle les vues au lieu de les recréer. - ◆
invertedretourne la liste : idéal pour une messagerie où les messages récents sont en bas.
6Vérifie ta compréhension
Question 1/3
Score 0
À quoi sert extraData ?
Envie d'essayer ? Ouvre le Labo et recopie les exemples pour les modifier.