All skills

Complete React Native and Expo optimization guide combining Callstack profiling with Vercel code patterns. Covers FPS, TTI, bundle size, memory, lists, animations, state, UI, and React Compiler. Use for any React Native performance, debugging, or best practices task.

Use this Skill: https://skilld.dev/gh/gigs-slc/react-native-skills/react-native

This session only. Nothing lands on disk.

referencesjs-profile-react.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Skill: Profile React Performance

Identify unnecessary re-renders and performance bottlenecks in React Native apps using React Native DevTools.

Quick Command

# Open React Native DevTools (press 'j' in Metro terminal)
# Or shake device → "Open DevTools"
# Go to Profiler tab → Start profiling → Perform actions → Stop

When to Use

  • App feels sluggish or janky during interactions
  • Need to identify which components re-render unnecessarily
  • Investigating slow list scrolling or form inputs
  • Before applying memoization or state management changes

Prerequisites

  • React Native DevTools accessible (press j in Metro or use Dev Menu)
  • App running in development mode
  • React DevTools version 6.0.1+ for React Compiler support

Note: This skill involves interpreting visual profiler output (flame graphs, component highlighting). AI agents cannot yet process screenshots autonomously. Use this as a guide while reviewing the profiler UI manually, or await MCP-based visual feedback integration (see roadmap).

Step-by-Step Instructions

1. Open React Native DevTools

# Option A: Press 'j' in Metro terminal (works with both RN CLI and Expo)
# Option B: Shake device / Cmd+D (iOS) / Cmd+M (Android) → "Open DevTools"
# Expo: Also accessible via Expo DevTools in browser

2. Configure Profiler Settings

  1. Go to Profiler tab
  2. Click gear icon (⚙️) for settings
  3. Enable:
    • "Highlight updates when components render"
    • "Record why each component rendered while profiling"

3. Record a Profiling Session

1. Click "Start profiling" (blue circle) or "Reload and start profiling"
2. Perform the interaction you want to analyze
3. Click "Stop profiling"

Use "Reload and start profiling" for startup performance analysis.

4. Analyze the Flame Graph

React DevTools Flamegraph

The flame graph shows component render hierarchy with timing:

Color indicators:

  • Yellow components: Most time spent rendering (focus here)
  • Green components: Fast/memoized
  • Gray components: Did not render

Right panel shows "Why did this render?":

  • Props changed (shows which prop, e.g., children, onPress)
  • Rendered at timestamps with duration (e.g., "3.7s for 0.9ms")

Click on a component to see:

  • Why it rendered (hook change, props change, parent re-render)
  • Render duration
  • Child components affected

5. Use Ranked View for Bottom-Up Analysis

Click "Ranked" tab to see components sorted by render time (slowest first).

6. Profile JavaScript CPU

For non-React performance issues:

  1. Go to JavaScript Profiler tab (enable in settings if hidden)
  2. Click "Start" to record
  3. Perform actions
  4. Click "Stop"
  5. Use Heavy (Bottom Up) view to find slowest functions

Code Examples

Before: Unnecessary Re-renders

const App = () => {
  const [count, setCount] = useState(0);
  
  return (
    <View>
      <Text>{count}</Text>
      {/* Button re-renders on every count change */}
      <Button onPress={() => setCount(count + 1)} title="Press" />
    </View>
  );
};

const Button = ({onPress, title}) => (
  <Pressable onPress={onPress}>
    <Text>{title}</Text>
  </Pressable>
);

After: Memoized

const App = () => {
  const [count, setCount] = useState(0);
  const onPressHandler = useCallback(() => setCount(c => c + 1), []);
  
  return (
    <View>
      <Text>{count}</Text>
      <Button onPress={onPressHandler} title="Press" />
    </View>
  );
};

const Button = memo(({onPress, title}) => (
  <Pressable onPress={onPress}>
    <Text>{title}</Text>
  </Pressable>
));

Interpreting Results

Symptom Likely Cause Solution
Many yellow components Cascading re-renders Add memoization or use React Compiler
"Props changed" on callbacks Inline functions recreated Use useCallback
"Parent component rendered" State too high in tree Move state down or use atomic state
Long JS thread block Heavy computation Move to background or use useDeferredValue

Common Pitfalls

  • Profiling in dev mode: Always disable JS Dev Mode for accurate measurements (Settings > JS Dev Mode on Android)
  • Not using production builds: Some issues only appear with minified code
  • Ignoring "Why did this render?": This tells you exactly what to fix

Related Skills

Source: SKILL.md on GitHub

2 alerts6mo4 checks · Risk HIGH
  • Gen Agent Trust Hub7mo

    The skill is a technical React Native guide that includes a high-risk remote code execution pattern for installing a performance tool.

  • Socket6mo

    No alerts

  • Snyk7mo

    Risk: MEDIUM · No issues

  • Runlayer7mo

    7/67 files flagged

Signed by skilld at 1d299ca. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Dormantupdated 8 months ago
Other metadata
metadata
{
  "author": "Callstack + Vercel",
  "version": "1.0.0",
  "tags": "react-native, expo, performance, optimization, patterns"
}

README badge

README badge for gigs-slc/react-native-skills/react-native