@ribcage/expo-performance
v1.0.4
Published
A performant module for tracking FPS and RAM usage in React Native applications
Maintainers
Readme
expo-performance
A performant Expo module for tracking FPS, RAM, and CPU usage in React Native applications.
Features
- 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
- iOS: Uses
- RAM Usage Monitoring: Memory consumption tracking
- iOS: Uses
task_infowithMACH_TASK_BASIC_INFO - Android: Uses
ActivityManagerandDebug.MemoryInfo
- iOS: Uses
- 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
Installation
npm install @ribcage/expo-performanceUsage
Basic Usage
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)}`);
console.log(`RAM: ${metrics.ramUsageInMB.toFixed(2)} MB`);
console.log(`CPU: ${metrics.cpuUsage.toFixed(1)}%`);
}, 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();React Component Example
import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import PerformanceMonitor, { PerformanceMetrics } from 'expo-performance';
function PerformanceDisplay() {
const [metrics, setMetrics] = useState<PerformanceMetrics | null>(null);
useEffect(() => {
const startMonitoring = async () => {
await PerformanceMonitor.startMonitoring(setMetrics, 1000);
};
startMonitoring();
return () => {
PerformanceMonitor.stopMonitoring();
};
}, []);
return (
<Text>
{metrics ?
`FPS: ${metrics.fps.toFixed(1)} | RAM: ${metrics.ramUsageInMB.toFixed(1)}MB | CPU: ${metrics.cpuUsage.toFixed(1)}%` :
'Loading...'
}
</Text>
);
}API Reference
Types
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;PerformanceMonitor Class Methods
startMonitoring(callback, intervalMs?): Promise<boolean>
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).
Implementation Details
FPS Tracking
iOS Implementation:
- Uses
CADisplayLinkattached to the main run loop - Counts frames over 1-second intervals
- Calculates FPS as
frameCount / elapsed_time - Similar approach to React Native's
RCTFPSGraph
Android Implementation:
- Uses
Choreographer.FrameCallbackfor frame callbacks - Tracks frame timestamps and calculates FPS
- Runs on the main thread for accurate UI frame tracking
RAM Usage Tracking
iOS Implementation:
- Uses
task_info()withMACH_TASK_BASIC_INFO - Reports
resident_size(physical memory footprint) - Same approach as React Native's
RCTGetResidentMemorySize
Android Implementation:
- Uses
Debug.MemoryInfo()for memory statistics - Reports
totalPrivateDirty(private dirty memory) - More accurate than
ActivityManager.getMemoryInfo()
Performance Considerations
- 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
Example App
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
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
