乐闻世界logo
搜索文章和话题

How to optimize Expo app performance? What are common performance issues?

2月21日 15:43

Performance optimization of Expo apps is key to ensuring a good user experience. Expo is based on React Native, so many React Native performance optimization techniques apply equally, while Expo also provides some specific optimization tools and strategies.

Performance Optimization Strategies:

  1. Component Rendering Optimization

Use React.memo, useMemo, and useCallback to reduce unnecessary renders:

typescript
// Use React.memo to avoid unnecessary re-renders const MyComponent = React.memo(({ data }) => { return <Text>{data.value}</Text>; }); // Use useMemo to cache computation results function ExpensiveComponent({ items }) { const sortedItems = useMemo(() => { return items.sort((a, b) => a.id - b.id); }, [items]); return <FlatList data={sortedItems} />; } // Use useCallback to cache functions function ParentComponent() { const handleClick = useCallback(() => { console.log('Clicked'); }, []); return <ChildComponent onClick={handleClick} />; }
  1. List Optimization

Use FlatList instead of ScrollView for long lists:

typescript
<FlatList data={items} renderItem={({ item }) => <Item item={item} />} keyExtractor={(item) => item.id} removeClippedSubviews={true} maxToRenderPerBatch={10} windowSize={10} initialNumToRender={10} getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })} />

Key Properties Explained:

  • removeClippedSubviews: Remove off-screen views
  • maxToRenderPerBatch: Number of items to render per batch
  • windowSize: Rendering window size
  • initialNumToRender: Initial number of items to render
  • getItemLayout: Provide item layout information
  1. Image Optimization

Use expo-image and image caching strategies:

typescript
import { Image } from 'expo-image'; <Image source={{ uri: 'https://example.com/image.jpg' }} style={{ width: 200, height: 200 }} cachePolicy="memory-disk" contentFit="cover" transition={200} />

Optimization Tips:

  • Use appropriate image sizes
  • Enable caching strategies
  • Use WebP format
  • Lazy load images
  1. Network Request Optimization

Use caching and request deduplication:

typescript
import { useQuery } from '@tanstack/react-query'; function UserProfile({ userId }) { const { data, isLoading } = useQuery({ queryKey: ['user', userId], queryFn: () => fetchUser(userId), staleTime: 5 * 60 * 1000, // 5 minutes cacheTime: 10 * 60 * 1000, // 10 minutes }); if (isLoading) return <Loading />; return <Text>{data.name}</Text>; }
  1. Animation Optimization

Use react-native-reanimated for high-performance animations:

typescript
import Animated, { useSharedValue, useAnimatedStyle, withTiming, } from 'react-native-reanimated'; function AnimatedBox() { const opacity = useSharedValue(0); const animatedStyle = useAnimatedStyle(() => { return { opacity: withTiming(opacity.value, { duration: 500 }), }; }); useEffect(() => { opacity.value = 1; }, []); return <Animated.View style={animatedStyle} />; }
  1. Memory Management

Release resources promptly:

typescript
// Cancel network requests useEffect(() => { const controller = new AbortController(); fetchData(controller.signal); return () => controller.abort(); }, []); // Clean up timers useEffect(() => { const timer = setInterval(() => { console.log('Tick'); }, 1000); return () => clearInterval(timer); }, []); // Clean up subscriptions useEffect(() => { const subscription = someEvent.subscribe(); return () => subscription.unsubscribe(); }, []);
  1. Bundle Optimization

Reduce app bundle size:

typescript
// Code splitting const LazyComponent = React.lazy(() => import('./LazyComponent')); // Dynamic imports const loadModule = async () => { const module = await import('./heavyModule'); module.doSomething(); }; // Remove unused dependencies npm prune
  1. Use Expo Performance Tools

Expo provides some performance monitoring tools:

typescript
import { Performance } from 'react-native'; // Record performance marks Performance.mark('component-start'); // After component renders Performance.mark('component-end'); // Measure performance Performance.measure('component-render', 'component-start', 'component-end');

Performance Analysis Tools:

  1. React DevTools Profiler

    • Analyze component rendering performance
    • Identify performance bottlenecks
    • Optimize render counts
  2. Flipper

    • Network request monitoring
    • Layout inspection
    • Memory analysis
  3. Expo DevTools

    • Real-time performance monitoring
    • Bundle size analysis
    • Load time tracking

Common Performance Issues and Solutions:

  1. List Scrolling Lag

    • Use FlatList instead of ScrollView
    • Enable removeClippedSubviews
    • Provide correct getItemLayout
  2. Slow Image Loading

    • Use expo-image
    • Enable caching
    • Use appropriate image sizes
  3. Slow App Startup

    • Optimize initialization code
    • Lazy load non-critical modules
    • Use splash screens
  4. Memory Leaks

    • Clean up subscriptions and timers promptly
    • Use WeakMap and WeakSet
    • Regularly check memory usage

Best Practices:

  1. Performance Monitoring: Regularly analyze apps with performance tools

  2. Progressive Optimization: Optimize critical paths first, then secondary features

  3. Test Coverage: Test performance on different devices

  4. Continuous Optimization: Make performance optimization a continuous process

  5. User Experience: Balance performance and functionality, prioritize core experience

Through systematic performance optimization, you can significantly improve the user experience and competitiveness of Expo apps.

标签:Expo