Module 9: Performance Optimization

Optimize React Native applications for better performance and user experience.

Back to Course|4.5 hours|Advanced

Performance Optimization

Optimize React Native applications for better performance and user experience.

Progress: 0/4 topics completed0%

Select Topics Overview

Performance Monitoring

Learn to monitor and measure React Native app performance using various tools and techniques

Content by: Pratik Keshvala

React Native Developer

Connect

Performance Tools

Use Flipper, React DevTools, and native profiling tools to identify performance bottlenecks in your React Native applications.

Key Performance Metrics

  • Frame Rate (FPS) - Target 60 FPS for smooth animations
  • Memory Usage - Monitor heap size and memory leaks
  • Bundle Size - Keep JavaScript bundle under 1MB
  • Startup Time - Target < 3 seconds for app launch
  • Time to Interactive - When app becomes fully responsive
  • Network Performance - API response times and data usage

Performance Monitoring Setup

Code Example
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet, ScrollView, TouchableOpacity } from 'react-native';
import { Performance } from 'react-native-performance';

const PerformanceMonitor = () => {
  const [metrics, setMetrics] = useState({
    fps: 0,
    memory: 0,
    bundleSize: 0,
    startupTime: 0,
  });

  useEffect(() => {
    // Monitor FPS
    const fpsInterval = setInterval(() => {
      Performance.getFPS().then(fps => {
        setMetrics(prev => ({ ...prev, fps }));
      });
    }, 1000);

    // Monitor Memory
    const memoryInterval = setInterval(() => {
      Performance.getMemoryUsage().then(memory => {
        setMetrics(prev => ({ ...prev, memory: memory.usedJSHeapSize }));
      });
    }, 2000);

    // Get Bundle Size
    Performance.getBundleSize().then(size => {
      setMetrics(prev => ({ ...prev, bundleSize: size }));
    });

    // Get Startup Time
    Performance.getStartupTime().then(time => {
      setMetrics(prev => ({ ...prev, startupTime: time }));
    });

    return () => {
      clearInterval(fpsInterval);
      clearInterval(memoryInterval);
    };
  }, []);

  const formatBytes = (bytes: number) => {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  const formatTime = (ms: number) => {
    return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(2)}s`;
  };

  const getPerformanceStatus = (metric: string, value: number) => {
    switch (metric) {
      case 'fps':
        return value >= 55 ? 'excellent' : value >= 45 ? 'good' : 'poor';
      case 'memory':
        return value < 50 * 1024 * 1024 ? 'excellent' : value < 100 * 1024 * 1024 ? 'good' : 'poor';
      case 'bundleSize':
        return value < 1024 * 1024 ? 'excellent' : value < 2 * 1024 * 1024 ? 'good' : 'poor';
      case 'startupTime':
        return value < 2000 ? 'excellent' : value < 3000 ? 'good' : 'poor';
      default:
        return 'unknown';
    }
  };

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'excellent': return '#4CAF50';
      case 'good': return '#FF9800';
      case 'poor': return '#F44336';
      default: return '#9E9E9E';
    }
  };

  return (
    <ScrollView style={styles.container}>
      <Text style={styles.title}>Performance Monitor</Text>
      
      <View style={styles.metricsContainer}>
        <View style={styles.metricCard}>
          <Text style={styles.metricLabel}>Frame Rate</Text>
          <Text style={[styles.metricValue, { color: getStatusColor(getPerformanceStatus('fps', metrics.fps)) }]}>
            {metrics.fps.toFixed(1)} FPS
          </Text>
          <Text style={styles.metricStatus}>
            Status: {getPerformanceStatus('fps', metrics.fps)}
          </Text>
        </View>

        <View style={styles.metricCard}>
          <Text style={styles.metricLabel}>Memory Usage</Text>
          <Text style={[styles.metricValue, { color: getStatusColor(getPerformanceStatus('memory', metrics.memory)) }]}>
            {formatBytes(metrics.memory)}
          </Text>
          <Text style={styles.metricStatus}>
            Status: {getPerformanceStatus('memory', metrics.memory)}
          </Text>
        </View>

        <View style={styles.metricCard}>
          <Text style={styles.metricLabel}>Bundle Size</Text>
          <Text style={[styles.metricValue, { color: getStatusColor(getPerformanceStatus('bundleSize', metrics.bundleSize)) }]}>
            {formatBytes(metrics.bundleSize)}
          </Text>
          <Text style={styles.metricStatus}>
            Status: {getPerformanceStatus('bundleSize', metrics.bundleSize)}
          </Text>
        </View>

        <View style={styles.metricCard}>
          <Text style={styles.metricLabel}>Startup Time</Text>
          <Text style={[styles.metricValue, { color: getStatusColor(getPerformanceStatus('startupTime', metrics.startupTime)) }]}>
            {formatTime(metrics.startupTime)}
          </Text>
          <Text style={styles.metricStatus}>
            Status: {getPerformanceStatus('startupTime', metrics.startupTime)}
          </Text>
        </View>
      </View>

      <View style={styles.recommendationsContainer}>
        <Text style={styles.recommendationsTitle}>Performance Recommendations</Text>
        <Text style={styles.recommendation}>
          • Use FlatList for large lists instead of ScrollView
        </Text>
        <Text style={styles.recommendation}>
          • Implement lazy loading for images and components
        </Text>
        <Text style={styles.recommendation}>
          • Use useMemo and useCallback for expensive calculations
        </Text>
        <Text style={styles.recommendation}>
          • Optimize images with proper formats and sizes
        </Text>
        <Text style={styles.recommendation}>
          • Remove unused dependencies and code
        </Text>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#f5f5f5',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    textAlign: 'center',
    marginBottom: 30,
    color: '#333',
  },
  metricsContainer: {
    gap: 15,
  },
  metricCard: {
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  metricLabel: {
    fontSize: 16,
    color: '#666',
    marginBottom: 5,
  },
  metricValue: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 5,
  },
  metricStatus: {
    fontSize: 14,
    color: '#999',
  },
  recommendationsContainer: {
    marginTop: 30,
    backgroundColor: 'white',
    padding: 20,
    borderRadius: 10,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3,
  },
  recommendationsTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 15,
  },
  recommendation: {
    fontSize: 14,
    color: '#666',
    marginBottom: 8,
    lineHeight: 20,
  },
});

export default PerformanceMonitor;
Swipe to see more code

🎯 Practice Exercise

Test your understanding of this topic:

Ready for the Next Module?

Continue your learning journey and master the next set of concepts.

Continue to Module 10