Optimize React Native apps for 60fps smooth performance on iOS and Android.
# React Native Performance Optimization
Master React Native performance with Google Antigravity IDE. This comprehensive guide covers rendering optimization, memory management, and native bridge efficiency for smooth 60fps mobile applications.
## Why Performance Matters?
React Native apps must maintain 60fps for smooth user experience. Google Antigravity IDE's Gemini 3 engine identifies performance bottlenecks and suggests optimizations automatically.
## List Optimization
```typescript
// components/OptimizedList.tsx
import { FlashList } from "@shopify/flash-list";
import { memo, useCallback, useMemo } from "react";
interface Item {
id: string;
title: string;
description: string;
}
interface ListProps {
data: Item[];
onItemPress: (id: string) => void;
}
// Memoize list item to prevent re-renders
const ListItem = memo(function ListItem({
item,
onPress,
}: {
item: Item;
onPress: () => void;
}) {
return (
<Pressable onPress={onPress} style={styles.item}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.description}>{item.description}</Text>
</Pressable>
);
});
export function OptimizedList({ data, onItemPress }: ListProps) {
// Memoize keyExtractor
const keyExtractor = useCallback((item: Item) => item.id, []);
// Memoize renderItem
const renderItem = useCallback(
({ item }: { item: Item }) => (
<ListItem item={item} onPress={() => onItemPress(item.id)} />
),
[onItemPress]
);
// Pre-calculate estimated item size
const estimatedItemSize = useMemo(() => 80, []);
return (
<FlashList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
estimatedItemSize={estimatedItemSize}
// Optimize for large lists
drawDistance={250}
// Remove items outside viewport
removeClippedSubviews={true}
/>
);
}
```
## Image Optimization
```typescript
// components/OptimizedImage.tsx
import FastImage from "react-native-fast-image";
import { useState } from "react";
interface OptimizedImageProps {
uri: string;
width: number;
height: number;
priority?: "low" | "normal" | "high";
}
export function OptimizedImage({
uri,
width,
height,
priority = "normal",
}: OptimizedImageProps) {
const [loaded, setLoaded] = useState(false);
return (
<View style={{ width, height }}>
{!loaded && <Skeleton width={width} height={height} />}
<FastImage
source={{
uri,
priority: FastImage.priority[priority],
cache: FastImage.cacheControl.immutable,
}}
style={{ width, height, opacity: loaded ? 1 : 0 }}
resizeMode={FastImage.resizeMode.cover}
onLoad={() => setLoaded(true)}
/>
</View>
);
}
// Preload images
FastImage.preload([
{ uri: "https://example.com/image1.jpg" },
{ uri: "https://example.com/image2.jpg" },
]);
```
## Animation Optimization
```typescript
// hooks/useAnimatedValue.ts
import Animated, {
useSharedValue,
useAnimatedStyle,
withSpring,
withTiming,
runOnJS,
} from "react-native-reanimated";
import { useCallback } from "react";
export function useCardAnimation() {
const scale = useSharedValue(1);
const translateY = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [
{ scale: scale.value },
{ translateY: translateY.value },
],
}));
const onPressIn = useCallback(() => {
scale.value = withSpring(0.95, { damping: 15 });
}, []);
const onPressOut = useCallback(() => {
scale.value = withSpring(1, { damping: 15 });
}, []);
const dismiss = useCallback((callback: () => void) => {
translateY.value = withTiming(-500, { duration: 300 }, () => {
runOnJS(callback)();
});
}, []);
return { animatedStyle, onPressIn, onPressOut, dismiss };
}
```
## Memory Management
```typescript
// hooks/useCleanup.ts
import { useEffect, useRef } from "react";
export function useImageCleanup() {
const mountedRef = useRef(true);
const abortControllerRef = useRef<AbortController>();
useEffect(() => {
return () => {
mountedRef.current = false;
abortControllerRef.current?.abort();
// Clear image cache on unmount
FastImage.clearMemoryCache();
};
}, []);
const fetchWithCleanup = useCallback(async (url: string) => {
abortControllerRef.current = new AbortController();
try {
const response = await fetch(url, {
signal: abortControllerRef.current.signal,
});
if (mountedRef.current) {
return await response.json();
}
} catch (error) {
if (error.name !== "AbortError") {
throw error;
}
}
}, []);
return { fetchWithCleanup, isMounted: mountedRef };
}
```
## Bridge Optimization
```typescript
// utils/batchUpdates.ts
import { unstable_batchedUpdates } from "react-native";
// Batch multiple state updates to reduce bridge calls
export function batchedStateUpdate(callback: () => void) {
unstable_batchedUpdates(callback);
}
// Example usage
function handleMultipleUpdates(data: ProcessedData) {
batchedStateUpdate(() => {
setItems(data.items);
setTotal(data.total);
setLoading(false);
});
}
// Use Hermes for better performance
// metro.config.js
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true, // Enable inline requires
},
}),
},
};
```
## Profiling Tools
```typescript
// utils/performance.ts
import { PerformanceObserver, performance } from "perf_hooks";
export function measureRenderTime(componentName: string) {
return function <T extends (...args: unknown[]) => unknown>(
target: T
): T {
return function (...args: Parameters<T>) {
const start = performance.now();
const result = target.apply(this, args);
const end = performance.now();
if (__DEV__) {
console.log(`${componentName} rendered in ${end - start}ms`);
}
return result;
} as T;
};
}
```
## Best Practices
- Use FlashList instead of FlatList for large lists
- Implement proper memoization with useMemo and useCallback
- Use Reanimated for 60fps animations on UI thread
- Enable Hermes JavaScript engine
- Profile with Flipper and React DevTools
- Minimize bridge communication with batched updates
Google Antigravity IDE automatically identifies performance bottlenecks and suggests optimizations for React Native applications.This React Native prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their react native implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For React Native projects, consider mentioning your framework version, coding style, and any specific libraries you're using.