Bundle Size Optimization
Reduce app bundle size and improve download/install times for React Native applications. This is a foundational concept in cross-platform mobile development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world React Native experience. Take your time with each section and practice the examples
Code Splitting
Implement code splitting and lazy loading to reduce initial bundle size and improve app startup time.. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Bundle Optimization Strategies
- Use dynamic imports for code splitting — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Remove unused dependencies and code — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Implement tree shaking for dead code elimination — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Use smaller alternative libraries — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Optimize images and assets — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Implement lazy loading for components — a critical concept in cross-platform mobile development that you will use frequently in real projects
Tree Shaking
Use tree shaking to eliminate unused code and reduce bundle size in production builds.. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Bundle Analysis Example
import React, { useState, lazy, Suspense } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, ActivityIndicator } from 'react-native';
// Lazy load heavy components
const HeavyComponent = lazy(() => import('./HeavyComponent'));
const ChartComponent = lazy(() => import('./ChartComponent'));
const BundleOptimizedApp = () => {
const [activeTab, setActiveTab] = useState('home');
const renderContent = () => {
switch (activeTab) {
case 'home':
return <HomeContent />;
case 'charts':
return (
<Suspense fallback={<LoadingSpinner />}>
<ChartComponent />
</Suspense>
);
case 'heavy':
return (
<Suspense fallback={<LoadingSpinner />}>
<HeavyComponent />
</Suspense>
);
default:
return <HomeContent />;
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>Bundle Optimized App</Text>
<View style={styles.tabContainer}>
<TouchableOpacity
style={[styles.tab, activeTab === 'home' && styles.activeTab]}
onPress={() => setActiveTab('home')}
>
<Text style={[styles.tabText, activeTab === 'home' && styles.activeTabText]}>
Home
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.tab, activeTab === 'charts' && styles.activeTab]}
onPress={() => setActiveTab('charts')}
>
<Text style={[styles.tabText, activeTab === 'charts' && styles.activeTabText]}>
Charts
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.tab, activeTab === 'heavy' && styles.activeTab]}
onPress={() => setActiveTab('heavy')}
>
<Text style={[styles.tabText, activeTab === 'heavy' && styles.activeTabText]}>
Heavy
</Text>
</TouchableOpacity>
</View>
<View style={styles.contentContainer}>
{renderContent()}
</View>
</View>
);
};
const HomeContent = () => (
<View style={styles.homeContainer}>
<Text style={styles.homeTitle}>Welcome to Optimized App</Text>
<Text style={styles.homeDescription}>
This app uses code splitting and lazy loading to optimize bundle size.
</Text>
</View>
);
const LoadingSpinner = () => (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color="#2196F3" />
<Text style={styles.loadingText}>Loading component...</Text>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 20,
color: '#333',
},
tabContainer: {
flexDirection: 'row',
marginBottom: 20,
backgroundColor: 'white',
borderRadius: 8,
padding: 4,
},
tab: {
flex: 1,
paddingVertical: 12,
paddingHorizontal: 16,
borderRadius: 6,
alignItems: 'center',
},
activeTab: {
backgroundColor: '#2196F3',
},
tabText: {
fontSize: 14,
fontWeight: '500',
color: '#666',
},
activeTabText: {
color: 'white',
},
contentContainer: {
flex: 1,
backgroundColor: 'white',
borderRadius: 8,
padding: 20,
},
homeContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
homeTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#333',
marginBottom: 15,
textAlign: 'center',
},
homeDescription: {
fontSize: 16,
color: '#666',
textAlign: 'center',
lineHeight: 24,
},
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
loadingText: {
marginTop: 10,
fontSize: 16,
color: '#666',
},
});
export default BundleOptimizedApp;