Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, and animations. Applies to tasks involving Hermes optimization, JS thread blocking, bridge overhead, FlashList, native modules, or debugging jank and frame drops.
.claude/skills/aiskillstore-react-native-best-practices/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 21% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -6% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 59% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 86% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 84% | 0% |
Performance optimization guide for React Native applications, covering JavaScript/React, Native (iOS/Android), and bundling optimizations. Based on Callstack's "Ultimate Guide to React Native Optimization".
Reference these guidelines when:
| 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-* |
Impact labels are triage hints: CRITICAL first, HIGH next, MEDIUM when evidence points there.
Follow this cycle for any performance issue: Measure → Optimize → Re-measure → Validate
If metrics did not improve, revert and try the next suggested fix.
estimatedItemSize, so do not flag it as missing there.useMemo or useCallback dependency changes unless behavior is demonstrably incorrect or profiling shows wasted work tied to that value.Profile first:
bashagent-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 20
Drive 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.
Common fixes:
useDeferredValue for expensive computationsAnalyze bundle:
bashnpx 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-checks
Verify improvement after optimization:
bash# Record baseline size before changes ls -lh output.js # e.g., Before: 2.1 MB # After applying fixes, re-bundle and compare npx react-native bundle --entry-file index.js --bundle-output output.js \ --platform ios --dev false --minify true ls -lh output.js # e.g., After: 1.6 MB (24% reduction)
Common fixes:
Measure TTI:
react-native-performance for markersCommon fixes:
Profile native:
Common fixes:
Full documentation with code examples in references/]references]:
js-*)| File | Impact | Description | |------|--------|-------------| | js-lists-flatlist-flashlist.md]js-lists-flatlist-flashlist] | CRITICAL | Replace ScrollView with virtualized lists | | js-profile-react.md]js-profile-react] | MEDIUM | agent-device react-devtools profiling | | js-measure-fps.md]js-measure-fps] | HIGH | FPS monitoring and measurement | | js-memory-leaks.md]js-memory-leaks] | MEDIUM | JS memory leak hunting | | js-atomic-state.md]js-atomic-state] | HIGH | Jotai/Zustand patterns | | js-concurrent-react.md]js-concurrent-react] | HIGH | useDeferredValue, useTransition | | js-react-compiler.md]js-react-compiler] | HIGH | Automatic memoization | | js-animations-reanimated.md]js-animations-reanimated] | MEDIUM | Reanimated worklets | | js-bottomsheet.md]js-bottomsheet] | HIGH | Bottom sheet optimization | | js-uncontrolled-components.md]js-uncontrolled-components] | HIGH | TextInput optimization |
native-*)| File | Impact | Description | |------|--------|-------------| | native-turbo-modules.md]native-turbo-modules] | HIGH | Building fast native modules | | native-sdks-over-polyfills.md]native-sdks-over-polyfills] | HIGH | Native vs JS libraries | | native-measure-tti.md]native-measure-tti] | HIGH | TTI measurement setup | | native-threading-model.md]native-threading-model] | HIGH | Turbo Module threads | | native-profiling.md]native-profiling] | MEDIUM | Xcode/Android Studio profiling | | native-platform-setup.md]native-platform-setup] | MEDIUM | iOS/Android tooling guide | | native-view-flattening.md]native-view-flattening] | MEDIUM | View hierarchy debugging | | native-memory-patterns.md]native-memory-patterns] | MEDIUM | C++/Swift/Kotlin memory | | native-memory-leaks.md]native-memory-leaks] | MEDIUM | Native memory leak hunting | | native-android-16kb-alignment.md]native-android-16kb-alignment] | CRITICAL | Third-party library alignment for Google Play |
bundle-*)| File | Impact | Description | |------|--------|-------------| | bundle-barrel-exports.md]bundle-barrel-exports] | CRITICAL | Avoid barrel imports | | bundle-analyze-js.md]bundle-analyze-js] | CRITICAL | JS bundle visualization | | bundle-tree-shaking.md]bundle-tree-shaking] | HIGH | Dead code elimination | | bundle-analyze-app.md]bundle-analyze-app] | HIGH | App size analysis | | bundle-r8-android.md]bundle-r8-android] | HIGH | Android code shrinking | | bundle-hermes-mmap.md]bundle-hermes-mmap] | HIGH | Disable bundle compression | | bundle-native-assets.md]bundle-native-assets] | HIGH | Asset catalog setup | | bundle-library-size.md]bundle-library-size] | MEDIUM | Evaluate dependencies | | bundle-code-splitting.md]bundle-code-splitting] | MEDIUM | Remote chunk loading safeguards |
| Problem | Start With | |---------|------------| | App feels slow/janky | js-measure-fps.md]js-measure-fps] → js-profile-react.md]js-profile-react] | | Too many re-renders | js-profile-react.md]js-profile-react] → js-react-compiler.md]js-react-compiler] | | Slow startup (TTI) | native-measure-tti.md]native-measure-tti] → bundle-analyze-js.md]bundle-analyze-js] | | Large app size | bundle-analyze-app.md]bundle-analyze-app] → bundle-r8-android.md]bundle-r8-android] | | Memory growing | js-memory-leaks.md]js-memory-leaks] or native-memory-leaks.md]native-memory-leaks] | | Animation drops frames | js-animations-reanimated.md]js-animations-reanimated] | | Bottom sheet jank/re-renders | js-bottomsheet.md]js-bottomsheet] → js-animations-reanimated.md]js-animations-reanimated] | | List scroll jank | js-lists-flatlist-flashlist.md]js-lists-flatlist-flashlist] | | TextInput lag | js-uncontrolled-components.md]js-uncontrolled-components] | | Native module slow | native-turbo-modules.md]native-turbo-modules] → native-threading-model.md]native-threading-model] | | Native library alignment issue | native-android-16kb-alignment.md]native-android-16kb-alignment] |
references]: references/ js-lists-flatlist-flashlist]: references/js-lists-flatlist-flashlist.md js-profile-react]: references/js-profile-react.md js-measure-fps]: references/js-measure-fps.md js-memory-leaks]: references/js-memory-leaks.md js-atomic-state]: references/js-atomic-state.md js-concurrent-react]: references/js-concurrent-react.md js-react-compiler]: references/js-react-compiler.md js-animations-reanimated]: references/js-animations-reanimated.md js-bottomsheet]: references/js-bottomsheet.md js-uncontrolled-components]: references/js-uncontrolled-components.md native-turbo-modules]: references/native-turbo-modules.md native-sdks-over-polyfills]: references/native-sdks-over-polyfills.md native-measure-tti]: references/native-measure-tti.md native-threading-model]: references/native-threading-model.md native-profiling]: references/native-profiling.md native-platform-setup]: references/native-platform-setup.md native-view-flattening]: references/native-view-flattening.md native-memory-patterns]: references/native-memory-patterns.md native-memory-leaks]: references/native-memory-leaks.md native-android-16kb-alignment]: references/native-android-16kb-alignment.md bundle-barrel-exports]: references/bundle-barrel-exports.md bundle-analyze-js]: references/bundle-analyze-js.md bundle-tree-shaking]: references/bundle-tree-shaking.md bundle-analyze-app]: references/bundle-analyze-app.md bundle-r8-android]: references/bundle-r8-android.md bundle-hermes-mmap]: references/bundle-hermes-mmap.md bundle-native-assets]: references/bundle-native-assets.md bundle-library-size]: references/bundle-library-size.md bundle-code-splitting]: references/bundle-code-splitting.md
Based on "The Ultimate Guide to React Native Optimization" by Callstack.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 45,130 | 24,511 | -46% | 1 | 1 | 0% | 5,369 | 6,523 | +21% | 0 | 0 | — |
case-02 | fail→fail | 27,400 | 18,490 | -33% | 1 | 1 | 0% | 4,717 | 6,659 | +41% | 0 | 0 | — |
case-03 | fail→pass | 45,989 | 23,261 | -49% | 1 | 1 | 0% | 7,534 | 7,118 | -6% | 0 | 0 | — |
case-04 | pass→pass | 30,725 | 23,788 | -23% | 1 | 1 | 0% | 5,222 | 7,479 | +43% | 0 | 0 | — |
case-05 | pass→pass | 22,973 | 21,876 | -5% | 1 | 1 | 0% | 3,539 | 6,722 | +90% | 0 | 0 | — |
case-06 | pass→pass | 44,735 | 21,020 | -53% | 1 | 1 | 0% | 3,794 | 6,334 | +67% | 0 | 0 | — |
case-07 | pass→pass | 31,173 | 20,420 | -34% | 1 | 1 | 0% | 2,817 | 5,871 | +108% | 0 | 0 | — |
case-08 | fail→pass | 22,965 | 12,993 | -43% | 1 | 1 | 0% | 2,916 | 4,624 | +59% | 0 | 0 | — |
case-19 | pass→pass | 22,983 | 13,384 | -42% | 1 | 1 | 0% | 2,978 | 5,696 | +91% | 0 | 0 | — |
case-09 | fail→pass | 21,614 | 10,806 | -50% | 1 | 1 | 0% | 2,799 | 5,212 | +86% | 0 | 0 | — |
case-10 | pass→pass | 16,167 | 14,326 | -11% | 1 | 1 | 0% | 2,904 | 5,063 | +74% | 0 | 0 | — |
case-11 | fail→pass | 24,987 | 19,741 | -21% | 1 | 1 | 0% | 3,035 | 5,592 | +84% | 0 | 0 | — |
case-12 | pass→pass | 18,380 | 13,500 | -27% | 1 | 1 | 0% | 2,081 | 4,674 | +125% | 0 | 0 | — |
case-13 | fail→pass | 19,385 | 11,564 | -40% | 1 | 1 | 0% | 2,288 | 5,038 | +120% | 0 | 0 | — |
case-14 | pass→pass | 16,562 | 15,175 | -8% | 1 | 1 | 0% | 1,978 | 4,977 | +152% | 0 | 0 | — |
case-15 | pass→pass | 19,995 | 17,521 | -12% | 1 | 1 | 0% | 2,370 | 5,266 | +122% | 0 | 0 | — |
case-16 | pass→pass | 13,556 | 12,207 | -10% | 1 | 1 | 0% | 1,475 | 4,451 | +202% | 0 | 0 | — |
case-17 | pass→pass | 29,083 | 21,346 | -27% | 1 | 1 | 0% | 3,315 | 5,993 | +81% | 0 | 0 | — |
case-18 | pass→pass | 24,039 | 18,515 | -23% | 1 | 1 | 0% | 3,034 | 5,505 | +81% | 0 | 0 | — |
case-20 | pass→pass | 18,108 | 15,683 | -13% | 1 | 1 | 0% | 2,856 | 4,928 | +73% | 0 | 0 | — |
case-21 | pass→pass | 41,238 | 20,900 | -49% | 1 | 1 | 0% | 2,712 | 5,873 | +117% | 0 | 0 | — |
case-22 | fail→pass | 21,885 | 16,602 | -24% | 1 | 1 | 0% | 3,039 | 4,983 | +64% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +32 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.