A performant module for tracking FPS and RAM usage in React Native applications
npm install @ribcage/expo-performanceA performant Expo module for tracking FPS, RAM, and CPU usage in React Native applications.
- FPS Tracking: Real-time frame rate monitoring using native APIs
- iOS: Uses CADisplayLink (same approach as React Native's performance monitor)
- Android: Uses Choreographer.FrameCallback
- RAM Usage Monitoring: Memory consumption tracking
- iOS: Uses task_info with MACH_TASK_BASIC_INFO
- Android: Uses ActivityManager and Debug.MemoryInfo
- CPU Usage Monitoring: Basic CPU usage tracking
- Cross-platform: Works on both iOS and Android
- TypeScript: Full TypeScript support with type definitions
- Performance Optimized: Minimal overhead, native implementations
- Simple Class-based API: Single class with intuitive methods
``bash`
npm install @ribcage/expo-performance
`typescript
import PerformanceMonitor from '@ribcage/expo-performance';
// Start monitoring with updates every second
const success = await PerformanceMonitor.startMonitoring((metrics) => {
console.log(FPS: ${metrics.fps.toFixed(1)});RAM: ${metrics.ramUsageInMB.toFixed(2)} MB
console.log();CPU: ${metrics.cpuUsage.toFixed(1)}%
console.log();
}, 1000);
// Get current metrics synchronously
const currentMetrics = PerformanceMonitor.getCurrentMetrics();
console.log(currentMetrics);
// Check if monitoring is active
console.log('Monitoring:', PerformanceMonitor.isMonitoring());
// Stop monitoring
PerformanceMonitor.stopMonitoring();
`
`typescript
import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import PerformanceMonitor, { PerformanceMetrics } from 'expo-performance';
function PerformanceDisplay() {
const [metrics, setMetrics] = useState
useEffect(() => {
const startMonitoring = async () => {
await PerformanceMonitor.startMonitoring(setMetrics, 1000);
};
startMonitoring();
return () => {
PerformanceMonitor.stopMonitoring();
};
}, []);
return (
{metrics ?
FPS: ${metrics.fps.toFixed(1)} | RAM: ${metrics.ramUsageInMB.toFixed(1)}MB | CPU: ${metrics.cpuUsage.toFixed(1)}% :
'Loading...'
}
);
}
`
`typescript
interface PerformanceMetrics {
fps: number; // Current frames per second
ramUsageInMB: number; // Memory usage in megabytes
cpuUsage: number; // CPU usage percentage
timestamp: number; // Timestamp when metrics were captured
}
type PerformanceCallback = (metrics: PerformanceMetrics) => void;
`
#### startMonitoring(callback, intervalMs?): Promise
Starts monitoring performance metrics.
- callback: Function to receive performance updatesintervalMs
- : Update interval in milliseconds (default: 1000)
- Returns: Promise that resolves to success status
#### stopMonitoring(): void
Stops performance monitoring.
#### getCurrentMetrics(): PerformanceMetrics
Gets current performance metrics synchronously.
#### isMonitoring(): boolean
Check if monitoring is currently active.
#### getDetailedMemoryInfo(): DetailedMemoryInfo | null
Get detailed memory information (platform-dependent).
#### getSystemInfo(): SystemInfo | null
Get system information (platform-dependent).
#### addListener(callback): Subscription
Add additional listener for performance updates.
#### forceGarbageCollection(): void
Force garbage collection (if supported by platform).
iOS Implementation:
- Uses CADisplayLink attached to the main run loopframeCount / elapsed_time
- Counts frames over 1-second intervals
- Calculates FPS as RCTFPSGraph
- Similar approach to React Native's
Android Implementation:
- Uses Choreographer.FrameCallback for frame callbacks
- Tracks frame timestamps and calculates FPS
- Runs on the main thread for accurate UI frame tracking
iOS Implementation:
- Uses task_info() with MACH_TASK_BASIC_INFOresident_size
- Reports (physical memory footprint)RCTGetResidentMemorySize
- Same approach as React Native's
Android Implementation:
- Uses Debug.MemoryInfo() for memory statisticstotalPrivateDirty
- Reports (private dirty memory)ActivityManager.getMemoryInfo()
- More accurate than
- Minimal Overhead: Native implementations with efficient monitoring
- Automatic Cleanup: Subscriptions automatically clean up resources
- Thread Safe: All operations are thread-safe
- Memory Efficient: No memory leaks, proper resource management
See the example/App.tsx` file for a complete example showing:
- Real-time performance monitoring
- Performance history tracking
- UI controls for starting/stopping monitoring
- Performance test components
MIT
Contributions are welcome! Please feel free to submit a Pull Request.