Onboarding
Step 1: Validate React Native Setup
Before applying performance optimizations, ensure:
- Expo CLI or React Native CLI is installed
- Verify with:
npx expo --versionandnpx react-native --version
- Verify with:
- Metro bundler is running (apply only for bundle analysis)
- React Native DevTools profiling is available through
agent-device react-devtools(apply only for React render profiling/debugging)- Run
agent-device react-devtools status, thenagent-device react-devtools wait --connected
- Run
Security Guardrails
- Review shell commands before running them and prefer version-pinned tooling from trusted sources.
- Do not pipe remote install scripts directly into a shell.
- Treat third-party packages as normal supply-chain dependencies that require provenance and version review.
- If using remote chunk loading, prefer app-bundled chunks or signed CI release manifests; hosted chunks must be first-party artifacts tied to the current release.
When to Load Reference Files
Load specific reference files from references/ based on the task:
JavaScript/React Performance (js-*)
- Debugging slow/janky UI or animations →
references/js-measure-fps.md - Investigating re-render issues →
references/js-profile-react.md→references/js-react-compiler.md - Optimizing list scrolling →
references/js-lists-flatlist-flashlist.md - Reducing re-renders with state management →
references/js-atomic-state.md - Using Concurrent React features →
references/js-concurrent-react.md - Enabling automatic memoization →
references/js-react-compiler.md - Optimizing animations →
references/js-animations-reanimated.md - Fixing TextInput lag →
references/js-uncontrolled-components.md - Hunting JavaScript memory leaks →
references/js-memory-leaks.md
Native Performance (native-*)
- Measuring startup time (TTI) →
references/native-measure-tti.md - Building native modules →
references/native-turbo-modules.md - Understanding native threading →
references/native-threading-model.md - Profiling native code →
references/native-profiling.md - Setting up native tooling →
references/native-platform-setup.md - Debugging view hierarchy →
references/native-view-flattening.md - Native memory patterns →
references/native-memory-patterns.md - Hunting native memory leaks →
references/native-memory-leaks.md - Choosing native SDKs vs polyfills →
references/native-sdks-over-polyfills.md - Fixing Android 16KB alignment →
references/native-android-16kb-alignment.md
Bundle & App Size (bundle-*)
- Analyzing bundle size →
references/bundle-analyze-js.md - Analyzing app size →
references/bundle-analyze-app.md - Fixing barrel imports →
references/bundle-barrel-exports.md - Enabling tree shaking →
references/bundle-tree-shaking.md - Android code shrinking →
references/bundle-r8-android.md - Optimizing Hermes bundle loading →
references/bundle-hermes-mmap.md - Managing native assets →
references/bundle-native-assets.md - Evaluating library size →
references/bundle-library-size.md - Code splitting →
references/bundle-code-splitting.md
Problem → Reference Mapping
Use this quick lookup when debugging specific issues:
| Problem | Start With |
|---|---|
| App feels slow/janky | references/js-measure-fps.md → references/js-profile-react.md |
| Too many re-renders | references/js-profile-react.md → references/js-react-compiler.md |
| Slow startup (TTI) | references/native-measure-tti.md → references/bundle-analyze-js.md |
| Large app size | references/bundle-analyze-app.md → references/bundle-r8-android.md |
| Memory growing | references/js-memory-leaks.md or references/native-memory-leaks.md |
| Animation drops frames | references/js-animations-reanimated.md |
| List scroll jank | references/js-lists-flatlist-flashlist.md |
| TextInput lag | references/js-uncontrolled-components.md |
| Native module slow | references/native-turbo-modules.md → references/native-threading-model.md |
| Native library alignment issue | references/native-android-16kb-alignment.md |
Quick Reference Commands
FPS & Re-renders
agent-device react-devtools status
agent-device react-devtools wait --connected
agent-device react-devtools profile start
agent-device react-devtools profile stop
agent-device react-devtools profile slow --limit 5
agent-device react-devtools profile rerenders --limit 5
agent-device react-devtools profile timeline --limit 20Drive the target interaction with normal agent-device commands between profile start and profile stop.
Manual fallback when agent-device is unavailable: open React Native DevTools from Metro (j) or the Dev Menu, use the Profiler tab, and record the same interaction.
For release-build React component profiling, connect @callstack/inspector first so React DevTools can attach to the release app, then run the agent-device react-devtools flow above.
Baseline runtime metrics should come from the target interaction itself:
- Capture commit timeline, re-render counts, slow components, and heaviest-commit breakdown.
- Treat component tree depth and count as supporting context only.
Common fixes:
- Replace ScrollView with FlatList/FlashList for lists
- After profiling shows cascading re-renders, use React Compiler for automatic memoization
- After profiling shows broad store/context updates, use atomic state (Jotai/Zustand) to reduce re-renders
- Use
useDeferredValuefor expensive computations
Review guardrails:
- Check library versions before suggesting API-specific fixes. FlashList v2 deprecates
estimatedItemSize. - Do not suggest
useMemooruseCallbackdependency changes without a reproducible correctness issue or profiling evidence. - Do not report stale closures unless the stale read path or repro is clear.
Analyze Bundle Size
npx react-native bundle \
--entry-file index.js \
--bundle-output output.js \
--platform ios \
--sourcemap-output output.js.map \
--dev false --minify true
npx source-map-explorer output.js --no-border-checksCommon fixes:
- Avoid barrel imports (import directly from source)
- Remove unnecessary Intl polyfills only after checking Hermes API and method coverage
- Evaluate tree shaking (Expo SDK 52+ experimental unused import/export removal, or Re.Pack only if already configured)
- Enable R8 for Android native code shrinking
Measure TTI
- Use
react-native-performancefor markers - Only measure cold starts (exclude warm/hot/prewarm)
Common fixes:
- For React Native 0.78 and earlier, disable Android JS bundle compression to enable Hermes mmap
- Use native navigation (react-native-screens)
- Preload commonly-used expensive screens before navigating to them
Native Performance
Profile native:
- iOS: Xcode Instruments → Time Profiler
- Android: Android Studio → CPU Profiler
Common fixes:
- Use background threads for heavy native work
- Prefer async over sync Turbo Module methods
- Use C++ for cross-platform performance-critical code
Priority Guidelines
Apply optimizations in this order:
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | FPS & Re-renders | CRITICAL | js-* |
| 2 | Bundle Size | CRITICAL | bundle-* |
| 3 | TTI Optimization | HIGH | native-*, bundle-* |
| 4 | Native Performance | HIGH | native-* |
| 5 | Memory Management | MEDIUM-HIGH | js-*, native-* |
| 6 | Animations | MEDIUM | js-* |
Attribution
Based on "The Ultimate Guide to React Native Optimization" by Callstack.