Performance Monitoring
Learn to monitor and measure React Native app performance using various tools and techniques
60 min•By Priygop Team•Last updated: Feb 2026
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
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;