Complete React Native Optimization Studio
Streamline your workflow with this skill for performance optimization for mobile React apps. Built for Claude Code with best practices and real-world patterns.
React Native Optimization Studio
Performance optimization toolkit for React Native applications covering rendering performance, memory management, bundle optimization, startup time reduction, and platform-specific tuning.
When to Use This Skill
Choose React Native Optimization when:
- App has janky animations or slow scrolling (FPS drops below 60)
- Startup time exceeds 2 seconds on target devices
- Memory usage causes crashes on lower-end devices
- Bundle size is too large for app store requirements
- Need to optimize list rendering for large datasets
Consider alternatives when:
- Building a new app from scratch — start with good architecture first
- Need native-only optimization — use Xcode Instruments or Android Profiler
- Performance issues are server-side — optimize API endpoints
Quick Start
# Activate React Native optimization claude skill activate complete-react-native-optimization-studio # Profile performance claude "Analyze the React Native app for performance bottlenecks" # Optimize a specific screen claude "Optimize the FlatList performance on the feed screen"
Example: Optimized FlatList
import { FlashList } from '@shopify/flash-list'; import { useCallback, useMemo } from 'react'; interface FeedScreenProps { posts: Post[]; } export function FeedScreen({ posts }: FeedScreenProps) { const renderItem = useCallback(({ item }: { item: Post }) => ( <PostCard post={item} /> ), []); const keyExtractor = useCallback((item: Post) => item.id, []); const getItemType = useCallback((item: Post) => { return item.hasImage ? 'image-post' : 'text-post'; }, []); return ( <FlashList data={posts} renderItem={renderItem} keyExtractor={keyExtractor} estimatedItemSize={200} getItemType={getItemType} // Performance optimizations removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={5} initialNumToRender={10} /> ); } // Memoized card component const PostCard = React.memo(function PostCard({ post }: { post: Post }) { return ( <View style={styles.card}> <Text style={styles.title}>{post.title}</Text> {post.hasImage && ( <FastImage source={{ uri: post.imageUrl, priority: FastImage.priority.normal }} style={styles.image} resizeMode={FastImage.resizeMode.cover} /> )} <Text style={styles.body}>{post.excerpt}</Text> </View> ); });
Core Concepts
Performance Metrics
| Metric | Target | How to Measure |
|---|---|---|
| JS Frame Rate | 60 FPS | React Native Perf Monitor |
| UI Frame Rate | 60 FPS | Platform profilers |
| TTI (Time to Interactive) | <2s | Flipper, custom timing |
| Memory Usage | <200MB | Xcode Instruments, Android Profiler |
| Bundle Size | <15MB (JS) | Metro bundle analysis |
| App Launch | <1.5s cold start | Platform startup profiling |
Common Optimization Areas
| Area | Problem | Solution |
|---|---|---|
| Lists | Scroll jank, high memory | FlashList, virtualization, memoization |
| Images | Slow loading, memory pressure | FastImage, caching, lazy loading |
| Navigation | Slow screen transitions | Lazy loading screens, native-stack |
| Animations | Dropped frames | Reanimated 3, native driver |
| Bridge | Serialization overhead | New Architecture (JSI/Turbo Modules) |
| Startup | Slow cold start | Hermes, inline requires, preloading |
// Animation optimization with Reanimated import Animated, { useSharedValue, useAnimatedStyle, withSpring, runOnUI, } from 'react-native-reanimated'; function AnimatedCard({ onPress }: { onPress: () => void }) { const scale = useSharedValue(1); const animatedStyle = useAnimatedStyle(() => ({ transform: [{ scale: scale.value }], })); const handlePressIn = () => { scale.value = withSpring(0.95, { damping: 15, stiffness: 150 }); }; const handlePressOut = () => { scale.value = withSpring(1, { damping: 15, stiffness: 150 }); }; return ( <Pressable onPressIn={handlePressIn} onPressOut={handlePressOut} onPress={onPress}> <Animated.View style={[styles.card, animatedStyle]}> {/* Card content */} </Animated.View> </Pressable> ); }
Configuration
| Parameter | Description | Default |
|---|---|---|
hermes_enabled | Use Hermes JavaScript engine | true |
new_architecture | Enable Fabric + TurboModules | false |
flipper_enabled | Enable Flipper debugging (dev only) | true |
inline_requires | Enable inline requires for faster startup | true |
ram_bundle | Use RAM bundle format | false |
proguard | Enable ProGuard for Android | true |
Best Practices
-
Use FlashList instead of FlatList for all lists — Shopify's FlashList is a drop-in replacement that recycles cell components instead of creating new ones, achieving consistent 60 FPS even with complex list items and thousands of entries.
-
Move all animations to the UI thread with Reanimated — React Native's Animated API with
useNativeDriver: trueis limited. Reanimated 3 runs animation worklets on the UI thread, enabling complex gesture-driven animations at 60 FPS without bridge overhead. -
Enable Hermes and inline requires for faster startup — Hermes precompiles JavaScript to bytecode, reducing parse time by 50-80%. Inline requires defer module loading until first use, reducing startup bundle evaluation.
-
Use React.memo with custom comparators for list items — Wrap list item components in
React.memoand provide a comparison function that checks only the props that affect rendering. This prevents unnecessary re-renders when parent state changes. -
Profile on real devices, not simulators — Simulators run on desktop hardware and don't reflect real device performance. Always test performance on the lowest-spec device in your target audience. Use release builds for accurate profiling — debug mode adds significant overhead.
Common Issues
FlatList drops frames when scrolling through image-heavy content. Replace FlatList with FlashList and use react-native-fast-image instead of the built-in Image component. FastImage handles caching, prioritization, and progressive loading. Set removeClippedSubviews={true} and reduce windowSize to limit off-screen rendering.
App crashes with "out of memory" on older Android devices. Large images are the most common cause. Resize images server-side to match display dimensions, use progressive JPEG loading, and implement image cache size limits. Monitor memory with Android Profiler and set largeHeap: true in AndroidManifest only as a last resort.
Navigation transitions are slow and choppy. Use @react-navigation/native-stack instead of @react-navigation/stack for native transition animations. Lazy-load screen components with React.lazy() and wrap with <Suspense>. Avoid heavy computations during the transition by deferring data loading with InteractionManager.runAfterInteractions().
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.