KlarkLabs
Retour au blog
Mobile
20 janvier 2026
4 min de lecture

Optimiser les performances React Native

Techniques avancées pour améliorer les performances de vos applications React Native en production.

React NativePerformanceMobile

Les performances sont souvent le talon d'Achille des applications React Native. Entre les re-renders inutiles, les animations saccadées et les longues durées de démarrage, les problèmes sont nombreux. Voici les techniques que nous appliquons systématiquement en production pour atteindre une fluidité proche du natif.

Comprendre le modèle de threading

React Native utilise trois threads principaux : le JS thread, le UI thread (natif) et le thread Shadow (layout). La plupart des problèmes de performances viennent d'un JS thread saturé qui bloque le rendu. Avec la New Architecture (Fabric + JSI), ce modèle évolue vers un rendu synchrone, mais la compréhension des fondamentaux reste essentielle.

1. Éviter les re-renders avec memo et useCallback

Le problème le plus courant est la recréation de fonctions et d'objets à chaque render, ce qui invalide les mémoïsations en aval.

// Mauvais : nouvelle référence à chaque render
const MyList = ({ userId }: { userId: string }) => {
  const handlePress = (item: Item) => {
    console.log(item.id, userId);
  };
 
  return <FlatList data={items} renderItem={({ item }) => (
    <ItemCard item={item} onPress={handlePress} />
  )} />;
};
 
// Correct : référence stable avec useCallback
const MyList = ({ userId }: { userId: string }) => {
  const handlePress = useCallback((item: Item) => {
    console.log(item.id, userId);
  }, [userId]);
 
  const renderItem = useCallback(({ item }: { item: Item }) => (
    <ItemCard item={item} onPress={handlePress} />
  ), [handlePress]);
 
  return <FlatList data={items} renderItem={renderItem} />;
};

2. Optimiser les FlatList avec getItemLayout

Si vos items ont une hauteur fixe, getItemLayout évite à React Native de mesurer chaque item au scroll, ce qui améliore drastiquement les performances des longues listes.

const ITEM_HEIGHT = 80;
const SEPARATOR_HEIGHT = 1;
 
<FlatList
  data={data}
  keyExtractor={(item) => item.id}
  getItemLayout={(_, index) => ({
    length: ITEM_HEIGHT,
    offset: (ITEM_HEIGHT + SEPARATOR_HEIGHT) * index,
    index,
  })}
  initialNumToRender={10}
  maxToRenderPerBatch={10}
  windowSize={5}
  removeClippedSubviews={true}
  renderItem={renderItem}
/>

3. Animations avec Reanimated 3

Toujours exécuter les animations sur le UI thread, jamais sur le JS thread. Reanimated 3 avec les worklets permet exactement cela.

import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withSpring,
  runOnJS,
} from "react-native-reanimated";
 
const PressableCard = ({ onPress }: { onPress: () => void }) => {
  const scale = useSharedValue(1);
 
  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ scale: scale.value }],
  }));
 
  const handlePressIn = () => {
    scale.value = withSpring(0.95, { damping: 15 });
  };
 
  const handlePressOut = () => {
    scale.value = withSpring(1, { damping: 15 }, (finished) => {
      if (finished) runOnJS(onPress)();
    });
  };
 
  return (
    <Animated.View style={animatedStyle}>
      <Pressable onPressIn={handlePressIn} onPressOut={handlePressOut}>
        {/* contenu */}
      </Pressable>
    </Animated.View>
  );
};

4. Réduire le temps de démarrage (TTI)

Le Time To Interactive (TTI) est la métrique la plus visible pour les utilisateurs. Plusieurs stratégies permettent de l'optimiser :

Lazy loading des écrans : Ne chargez que les écrans visibles au démarrage.

// navigation/RootNavigator.tsx
const HomeScreen = lazy(() => import("../screens/HomeScreen"));
const ProfileScreen = lazy(() => import("../screens/ProfileScreen"));
const SettingsScreen = lazy(() => import("../screens/SettingsScreen"));

Hermes : Activez le moteur JavaScript Hermes (activé par défaut depuis RN 0.70) qui réduit le TTI de 30 à 40% grâce au bytecode précompilé.

5. Profilage avec Flipper et Flashlight

Ne pas optimiser à l'aveugle. Utilisez Flipper avec le plugin React DevTools pour identifier les composants qui re-rendent inutilement. Pour une analyse plus approfondie, l'outil Flashlight permet de mesurer le score de performance global de votre application sur un vrai device Android.

# Installation de Flashlight CLI
npm install -g @perf-tools/flashlight
 
# Mesure de performance sur un parcours utilisateur
flashlight measure --apk ./app-release.apk --test ./e2e/homeFlow.js

Résultats observés

En appliquant ces techniques sur une application de e-commerce à 500K utilisateurs actifs :

  • Réduction du TTI de 2.8s à 1.1s
  • Suppression de 73% des re-renders inutiles
  • Score FPS moyen amélioré de 42 à 58 FPS sur les listes scrollables

Conclusion

L'optimisation React Native est un effort continu qui nécessite de mesurer avant d'optimiser. Commencez par identifier vos bottlenecks réels avec les outils de profilage, appliquez les corrections ciblées, puis mesurez à nouveau. Les gains les plus significatifs viennent généralement des FlatList mal configurées et des animations exécutées sur le mauvais thread.

Klark Labs
Technology Studio