Skip to content

thewoowon/react-native-perf-hud

Repository files navigation

react-native-perf-hud

Real-time performance monitoring overlay for React Native apps. Track FPS, memory usage, and component render counts during development.

Features

  • JS FPS Monitoring: Track JavaScript thread frame rate in real-time
  • Native UI FPS Monitoring: Monitor actual UI thread performance (iOS & Android)
  • Memory Tracking: Monitor heap memory usage (Hermes engine supported)
  • Render Count Tracking: Monitor component re-render frequency
  • Draggable Overlay: Move the HUD anywhere on screen with drag gestures
  • Lightweight Overlay: Minimal, toggleable HUD that stays out of your way
  • Customizable: Position, theme, and alert thresholds
  • Development-Only: Easy to disable for production builds
  • TypeScript Support: Full type definitions included

Installation

npm install react-native-perf-hud
# or
yarn add react-native-perf-hud

iOS Setup

Run pod install:

cd ios && pod install

Android Setup

No additional setup required! The native module is automatically linked.

Optional: Draggable Overlay

For draggable overlay support, install react-native-gesture-handler:

npm install react-native-gesture-handler
# or
yarn add react-native-gesture-handler

Then enable it in your config:

<PerfMonitorProvider config={{ enabled: __DEV__, draggable: true }}>
  <YourApp />
</PerfMonitorProvider>

Quick Start

1. Wrap your app with PerfMonitorProvider

import { PerfMonitorProvider } from 'react-native-perf-hud';

export default function App() {
  return (
    <PerfMonitorProvider config={{ enabled: __DEV__ }}>
      <YourApp />
    </PerfMonitorProvider>
  );
}

That's it! The performance overlay will automatically appear in the top-right corner.

Configuration

The PerfMonitorProvider accepts a config prop with the following options:

type PerfMonitorConfig = {
  enabled?: boolean;                // Enable/disable monitoring (default: true)
  showOverlay?: boolean;            // Show the overlay HUD (default: true)
  position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
  samplingIntervalMs?: number;      // Update interval in ms (default: 500)
  theme?: 'dark' | 'light' | 'auto'; // Overlay theme (default: 'dark')
  zIndex?: number;                  // Overlay z-index (default: 9999)
  draggable?: boolean;              // Enable drag to reposition (default: false)
  minimized?: boolean;              // Start in minimized state (default: false)
  alerts?: {
    lowFpsThreshold?: number;       // FPS threshold for warning (default: 30)
    highMemoryThreshold?: number;   // Memory threshold in MB (default: 200)
  };
};

Example with custom config

<PerfMonitorProvider
  config={{
    enabled: __DEV__,
    position: 'bottom-right',
    theme: 'light',
    samplingIntervalMs: 1000,
    alerts: {
      lowFpsThreshold: 45,
    },
  }}
>
  <YourApp />
</PerfMonitorProvider>

API

usePerfState()

Hook to access current performance metrics programmatically.

import { usePerfState } from 'react-native-perf-hud';

function MyComponent() {
  const metrics = usePerfState();

  console.log(metrics.jsFps);      // Current JS FPS
  console.log(metrics.renderCount); // Total render count
  console.log(metrics.memoryMb);    // Memory usage (if available)

  return <View>...</View>;
}

useRenderCount(componentName?: string)

Hook to track render count for a specific component.

import { useRenderCount } from 'react-native-perf-hud';

function MyComponent() {
  const renderCount = useRenderCount('MyComponent');

  console.log(`MyComponent rendered ${renderCount} times`);

  return <View>...</View>;
}

PerfOverlay

The overlay component is automatically rendered by PerfMonitorProvider when showOverlay: true. You can also render it manually:

import { PerfMonitorProvider, PerfOverlay } from 'react-native-perf-hud';

function App() {
  return (
    <PerfMonitorProvider config={{ enabled: __DEV__, showOverlay: false }}>
      <YourApp />
      {/* Render overlay manually */}
      <PerfOverlay />
    </PerfMonitorProvider>
  );
}

Usage Patterns

Development-only monitoring

<PerfMonitorProvider config={{ enabled: __DEV__ }}>
  <App />
</PerfMonitorProvider>

Debug specific screens

function ProfileScreen() {
  const renderCount = useRenderCount('ProfileScreen');

  // Log when renders exceed threshold
  useEffect(() => {
    if (renderCount > 50) {
      console.warn('ProfileScreen re-rendered too many times!');
    }
  }, [renderCount]);

  return <View>...</View>;
}

Custom performance monitoring

function Dashboard() {
  const metrics = usePerfState();

  useEffect(() => {
    if (metrics.jsFps < 30) {
      // Performance degraded, maybe reduce animations
      console.warn('Low FPS detected:', metrics.jsFps);
    }
  }, [metrics.jsFps]);

  return <View>...</View>;
}

Overlay Controls

  • Tap the overlay: Toggle between expanded and minimized states
  • Minimized: Shows only current FPS
  • Expanded: Shows all metrics (FPS, Memory, Render Count)

Metrics Explained

JS FPS

Frame rate of the JavaScript thread, calculated using requestAnimationFrame. Ideal value is 60 FPS. Values below 30 FPS indicate performance issues.

UI FPS (Native)

Frame rate of the actual UI thread, measured using platform-specific APIs:

  • iOS: CADisplayLink for accurate display refresh rate
  • Android: Choreographer for frame timing

Shows "N/A" if native module is not available. This is the most accurate indicator of visual smoothness.

Render Count

Total number of component renders tracked across all components using useRenderCount(). Helps identify unnecessary re-renders.

Memory

Memory usage in MB. Shows heap memory usage when running on Hermes engine. Displays "N/A" for other JS engines or when memory tracking is unavailable.

Draggable Overlay

When draggable: true is enabled in the config (requires react-native-gesture-handler), you can drag the overlay to reposition it anywhere on the screen. The overlay will remember its position while dragging.

Roadmap

Phase 1 (✅ Completed)

  • ✅ JS FPS monitoring
  • ✅ Expandable/collapsible overlay
  • useRenderCount hook
  • ✅ Configurable position and theme

Phase 2 (✅ Completed)

  • ✅ Memory usage tracking (Hermes support)
  • ✅ Draggable overlay

Phase 3 (✅ Completed)

  • ✅ Native UI FPS tracking (iOS CADisplayLink, Android Choreographer)

Phase 4 (🔜 Planned)

  • 🔜 Network request monitoring plugin
  • 🔜 React Profiler auto-tracking
  • 🔜 Performance alerts and notifications
  • 🔜 Export performance data (CSV, JSON)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Troubleshooting

Overlay not showing

  • Ensure enabled: true and showOverlay: true in config
  • Check that PerfMonitorProvider wraps your app
  • Verify no z-index conflicts with other overlays

FPS shows 0

  • Make sure the app is actively rendering
  • Check that JavaScript thread is not blocked

TypeScript errors

  • Ensure you have TypeScript 5.0+ installed
  • Check that @types/react and @types/react-native are installed

Support

About

React Native Performance & Memory Overlay

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published