Prerequisites
- Understanding of ES6 modules and import/export statements 📝
- Knowledge of Promises and async/await syntax ⚡
- Familiarity with JavaScript bundlers and build tools 💻
What you'll learn
- Master dynamic import syntax and lazy loading patterns 🎯
- Implement efficient code splitting and bundle optimization 🏗️
- Build conditional loading systems for better performance 🐛
- Create sophisticated module loading strategies ✨
🎯 Introduction
Welcome to the express lane of module loading! ⚡ If static imports were like having all groceries delivered at once (whether you need them or not), then dynamic imports are like ordering exactly what you want, when you want it - just-in-time delivery for your code!
Dynamic imports revolutionize how we load modules by allowing runtime, conditional, and lazy loading. This powerful feature enables code splitting, reduces initial bundle sizes, improves performance, and creates more responsive applications. Instead of loading everything upfront, you can strategically load modules only when they’re actually needed.
By the end of this tutorial, you’ll be a dynamic import master, capable of creating highly optimized applications that load efficiently and respond quickly to user interactions. Let’s dive into the world of on-demand module loading! 🌟
📚 Understanding Dynamic Imports
🤔 What Are Dynamic Imports?
Dynamic imports allow you to import modules at runtime using the import()
function, which returns a Promise that resolves to the module. Unlike static imports that are resolved at compile time, dynamic imports are evaluated during execution.
// 🌟 Static imports - loaded at compile time
import { UserService } from './services/UserService';
import { PaymentProcessor } from './services/PaymentProcessor';
import { AnalyticsTracker } from './services/AnalyticsTracker';
// All modules are bundled together and loaded immediately
console.log('All services loaded at startup');
// ⚡ Dynamic imports - loaded at runtime
const loadUserService = async () => {
const { UserService } = await import('./services/UserService');
return new UserService();
};
const loadPaymentProcessor = async () => {
const { PaymentProcessor } = await import('./services/PaymentProcessor');
return new PaymentProcessor();
};
const loadAnalytics = async () => {
const { AnalyticsTracker } = await import('./services/AnalyticsTracker');
return new AnalyticsTracker();
};
// Modules are loaded only when needed
console.log('Services loaded on demand');
// 🎯 Dynamic import syntax variations
// 📦 Import entire module
const modulePromise = import('./module');
modulePromise.then(module => {
// Use module.default for default export
// Use module.namedExport for named exports
});
// 🎯 Import with destructuring
const { namedExport, anotherExport } = await import('./module');
// 📄 Import default export
const { default: DefaultExport } = await import('./module');
// 🔧 Import with error handling
try {
const module = await import('./module');
console.log('Module loaded successfully');
} catch (error) {
console.error('Failed to load module:', error);
}
// 🎮 Let's create a comprehensive dynamic import system
console.log('⚡ Dynamic Import Examples');
// 🏗️ Dynamic module loader class
class DynamicModuleLoader {
// 📊 Track loading statistics
private loadingStats = {
successful: 0,
failed: 0,
cached: 0,
totalTime: 0
};
// 🗂️ Module cache
private moduleCache = new Map<string, any>();
// ⚡ Load module dynamically with caching
async loadModule<T = any>(
modulePath: string,
options: {
useCache?: boolean;
timeout?: number;
retries?: number;
onProgress?: (progress: number) => void;
} = {}
): Promise<T> {
const {
useCache = true,
timeout = 5000,
retries = 3,
onProgress
} = options;
console.log(`⚡ Loading module: ${modulePath}`);
const startTime = performance.now();
// 🗂️ Check cache first
if (useCache && this.moduleCache.has(modulePath)) {
console.log(`📦 Using cached module: ${modulePath}`);
this.loadingStats.cached++;
onProgress?.(100);
return this.moduleCache.get(modulePath);
}
// 🔄 Attempt loading with retries
for (let attempt = 1; attempt <= retries; attempt++) {
try {
onProgress?.(25 * attempt);
// ⏱️ Load with timeout
const module = await this.loadWithTimeout(modulePath, timeout);
// 🗂️ Cache the module
if (useCache) {
this.moduleCache.set(modulePath, module);
}
// 📊 Update statistics
const endTime = performance.now();
this.loadingStats.successful++;
this.loadingStats.totalTime += endTime - startTime;
console.log(`✅ Module loaded successfully: ${modulePath} (attempt ${attempt})`);
onProgress?.(100);
return module;
} catch (error) {
console.warn(`⚠️ Failed to load module ${modulePath} (attempt ${attempt}):`, error);
if (attempt === retries) {
this.loadingStats.failed++;
throw new Error(`Failed to load module ${modulePath} after ${retries} attempts`);
}
// 💤 Wait before retry
await this.delay(1000 * attempt);
}
}
throw new Error(`Failed to load module: ${modulePath}`);
}
// ⏱️ Load module with timeout
private async loadWithTimeout(modulePath: string, timeout: number): Promise<any> {
return Promise.race([
import(modulePath),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Module load timeout')), timeout)
)
]);
}
// 💤 Delay utility
private delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 📦 Load multiple modules in parallel
async loadModules(
modulePaths: string[],
options: {
useCache?: boolean;
failFast?: boolean;
onProgress?: (loaded: number, total: number) => void;
} = {}
): Promise<any[]> {
const { useCache = true, failFast = false, onProgress } = options;
console.log(`📦 Loading ${modulePaths.length} modules in parallel...`);
const loadPromises = modulePaths.map(async (path, index) => {
try {
const module = await this.loadModule(path, { useCache });
onProgress?.(index + 1, modulePaths.length);
return { success: true, module, path };
} catch (error) {
console.error(`❌ Failed to load module: ${path}`, error);
if (failFast) {
throw error;
}
return { success: false, error, path };
}
});
const results = await Promise.all(loadPromises);
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`📊 Parallel loading complete: ${successful.length} success, ${failed.length} failed`);
return results;
}
// 🎯 Load module based on condition
async conditionalLoad<T>(
condition: boolean | (() => boolean),
modulePath: string,
fallbackPath?: string
): Promise<T | null> {
const shouldLoad = typeof condition === 'function' ? condition() : condition;
if (shouldLoad) {
console.log(`✅ Condition met, loading: ${modulePath}`);
return await this.loadModule<T>(modulePath);
} else if (fallbackPath) {
console.log(`🔄 Loading fallback: ${fallbackPath}`);
return await this.loadModule<T>(fallbackPath);
} else {
console.log(`❌ Condition not met, skipping load`);
return null;
}
}
// 🌊 Load modules in sequence (waterfall)
async loadSequentially(
modulePaths: string[],
onProgress?: (loaded: number, total: number) => void
): Promise<any[]> {
console.log(`🌊 Loading ${modulePaths.length} modules sequentially...`);
const results: any[] = [];
for (let i = 0; i < modulePaths.length; i++) {
const path = modulePaths[i];
try {
const module = await this.loadModule(path);
results.push({ success: true, module, path });
onProgress?.(i + 1, modulePaths.length);
} catch (error) {
console.error(`❌ Failed to load module: ${path}`, error);
results.push({ success: false, error, path });
}
}
console.log(`✅ Sequential loading complete`);
return results;
}
// 🎭 Load module with feature detection
async loadWithFeatureDetection(
features: Record<string, () => boolean>,
moduleMap: Record<string, string>
): Promise<any[]> {
console.log('🎭 Loading modules based on feature detection...');
const modulesToLoad: string[] = [];
// 🔍 Check which features are available
for (const [feature, detector] of Object.entries(features)) {
if (detector()) {
const modulePath = moduleMap[feature];
if (modulePath) {
console.log(`✅ Feature '${feature}' detected, will load: ${modulePath}`);
modulesToLoad.push(modulePath);
}
} else {
console.log(`❌ Feature '${feature}' not available`);
}
}
// 📦 Load all detected modules
return await this.loadModules(modulesToLoad);
}
// 🔄 Preload modules for better performance
async preloadModules(
modulePaths: string[],
options: {
priority?: 'high' | 'low';
delay?: number;
batchSize?: number;
} = {}
): Promise<void> {
const { priority = 'low', delay = 0, batchSize = 3 } = options;
console.log(`🔄 Preloading ${modulePaths.length} modules (priority: ${priority})...`);
// 💤 Delay for low priority preloading
if (priority === 'low' && delay > 0) {
await this.delay(delay);
}
// 📦 Load in batches to avoid overwhelming the network
for (let i = 0; i < modulePaths.length; i += batchSize) {
const batch = modulePaths.slice(i, i + batchSize);
console.log(`📦 Preloading batch ${Math.floor(i / batchSize) + 1}...`);
await Promise.allSettled(
batch.map(path => this.loadModule(path, { useCache: true }))
);
// 🌬️ Breathe between batches
if (i + batchSize < modulePaths.length) {
await this.delay(100);
}
}
console.log('✅ Preloading complete');
}
// 📊 Get loading statistics
getStats(): {
successful: number;
failed: number;
cached: number;
totalTime: number;
averageTime: number;
cacheHitRate: number;
} {
const totalLoads = this.loadingStats.successful + this.loadingStats.failed;
return {
...this.loadingStats,
averageTime: totalLoads > 0 ? this.loadingStats.totalTime / totalLoads : 0,
cacheHitRate: totalLoads > 0 ? this.loadingStats.cached / totalLoads : 0
};
}
// 🧹 Clear module cache
clearCache(pattern?: string): number {
let cleared = 0;
if (pattern) {
const regex = new RegExp(pattern);
for (const [key] of this.moduleCache) {
if (regex.test(key)) {
this.moduleCache.delete(key);
cleared++;
}
}
} else {
cleared = this.moduleCache.size;
this.moduleCache.clear();
}
console.log(`🧹 Cleared ${cleared} modules from cache`);
return cleared;
}
}
// 🎮 Usage examples
const dynamicLoadingDemo = async (): Promise<void> => {
const loader = new DynamicModuleLoader();
// ⚡ Basic dynamic loading
try {
const userModule = await loader.loadModule('./services/UserService');
console.log('User service loaded:', userModule);
} catch (error) {
console.error('Failed to load user service:', error);
}
// 📦 Parallel loading
const moduleResults = await loader.loadModules([
'./components/Header',
'./components/Footer',
'./components/Sidebar'
], {
onProgress: (loaded, total) => {
console.log(`Progress: ${loaded}/${total} modules loaded`);
}
});
// 🎯 Conditional loading
const shouldLoadPayments = true;
const paymentModule = await loader.conditionalLoad(
shouldLoadPayments,
'./services/PaymentService',
'./services/BasicPaymentService'
);
// 🎭 Feature-based loading
const featureModules = await loader.loadWithFeatureDetection(
{
webgl: () => !!window.WebGLRenderingContext,
webworkers: () => typeof Worker !== 'undefined',
indexeddb: () => !!window.indexedDB
},
{
webgl: './graphics/WebGLRenderer',
webworkers: './workers/BackgroundProcessor',
indexeddb: './storage/IndexedDBManager'
}
);
// 📊 Show statistics
console.log('📊 Loading Statistics:', loader.getStats());
};
// 🎯 Advanced dynamic import patterns
interface DynamicImportConfig {
modulePath: string;
condition?: () => boolean;
fallback?: string;
preload?: boolean;
cache?: boolean;
timeout?: number;
}
// 🏗️ Smart module loader with advanced features
class SmartModuleLoader {
private static instance: SmartModuleLoader;
private loadedModules = new Map<string, any>();
private loadingPromises = new Map<string, Promise<any>>();
static getInstance(): SmartModuleLoader {
if (!SmartModuleLoader.instance) {
SmartModuleLoader.instance = new SmartModuleLoader();
}
return SmartModuleLoader.instance;
}
// 🚀 Route-based lazy loading
async loadRouteComponent(route: string): Promise<any> {
console.log(`🚀 Loading route component: ${route}`);
// 🗺️ Route mapping
const routeMap: Record<string, string> = {
'/home': './pages/HomePage',
'/about': './pages/AboutPage',
'/products': './pages/ProductsPage',
'/contact': './pages/ContactPage',
'/admin': './pages/AdminPage',
'/profile': './pages/ProfilePage'
};
const modulePath = routeMap[route];
if (!modulePath) {
throw new Error(`No component found for route: ${route}`);
}
// 🔍 Check if already loading
if (this.loadingPromises.has(route)) {
console.log(`⏳ Route component already loading: ${route}`);
return await this.loadingPromises.get(route);
}
// 📦 Start loading
const loadingPromise = this.loadWithPreloading(modulePath, route);
this.loadingPromises.set(route, loadingPromise);
try {
const component = await loadingPromise;
this.loadingPromises.delete(route);
return component;
} catch (error) {
this.loadingPromises.delete(route);
throw error;
}
}
// 🔄 Load with intelligent preloading
private async loadWithPreloading(modulePath: string, route: string): Promise<any> {
// 📦 Load main component
const mainComponent = await import(modulePath);
// 🎯 Preload related components based on route
this.preloadRelatedComponents(route);
return mainComponent;
}
// 🎯 Preload related components
private preloadRelatedComponents(route: string): void {
// 🔗 Define component relationships
const relatedComponents: Record<string, string[]> = {
'/home': ['./components/FeaturedProducts', './components/Newsletter'],
'/products': ['./components/ProductFilter', './components/ShoppingCart'],
'/profile': ['./components/ProfileEditor', './components/AccountSettings'],
'/admin': ['./components/UserManagement', './components/Analytics']
};
const related = relatedComponents[route];
if (related) {
console.log(`🔄 Preloading related components for ${route}:`, related);
// 🌊 Preload in background
setTimeout(() => {
related.forEach(async (componentPath) => {
try {
await import(componentPath);
console.log(`✅ Preloaded: ${componentPath}`);
} catch (error) {
console.warn(`⚠️ Failed to preload: ${componentPath}`, error);
}
});
}, 100);
}
}
// 🎭 Load theme dynamically
async loadTheme(themeName: string): Promise<any> {
console.log(`🎭 Loading theme: ${themeName}`);
const themeMap: Record<string, string> = {
dark: './themes/DarkTheme',
light: './themes/LightTheme',
high_contrast: './themes/HighContrastTheme',
colorful: './themes/ColorfulTheme'
};
const themePath = themeMap[themeName];
if (!themePath) {
throw new Error(`Theme not found: ${themeName}`);
}
try {
const theme = await import(themePath);
console.log(`✅ Theme loaded: ${themeName}`);
return theme.default || theme;
} catch (error) {
console.error(`❌ Failed to load theme: ${themeName}`, error);
// 🔄 Fallback to light theme
const fallback = await import('./themes/LightTheme');
return fallback.default || fallback;
}
}
// 🌍 Load localization dynamically
async loadLocalization(locale: string): Promise<any> {
console.log(`🌍 Loading localization: ${locale}`);
// 🗂️ Normalize locale
const normalizedLocale = locale.toLowerCase().replace('-', '_');
try {
// 🎯 Try specific locale first (e.g., en_US)
const localization = await import(`./i18n/${normalizedLocale}.json`);
console.log(`✅ Localization loaded: ${normalizedLocale}`);
return localization.default || localization;
} catch (error) {
// 🔄 Fallback to base language (e.g., en)
const baseLocale = normalizedLocale.split('_')[0];
try {
const fallback = await import(`./i18n/${baseLocale}.json`);
console.log(`✅ Fallback localization loaded: ${baseLocale}`);
return fallback.default || fallback;
} catch (fallbackError) {
// 🌐 Ultimate fallback to English
console.warn(`⚠️ Fallback to English localization`);
const english = await import('./i18n/en.json');
return english.default || english;
}
}
}
// 🎮 Load feature modules based on user permissions
async loadPermissionBasedModules(
userPermissions: string[]
): Promise<Record<string, any>> {
console.log('🎮 Loading modules based on permissions:', userPermissions);
// 🔐 Permission to module mapping
const permissionModules: Record<string, string> = {
'admin': './modules/AdminModule',
'user_management': './modules/UserManagementModule',
'analytics': './modules/AnalyticsModule',
'billing': './modules/BillingModule',
'support': './modules/SupportModule',
'settings': './modules/SettingsModule'
};
const loadedModules: Record<string, any> = {};
// 📦 Load modules for each permission
const loadPromises = userPermissions
.filter(permission => permissionModules[permission])
.map(async (permission) => {
try {
const module = await import(permissionModules[permission]);
loadedModules[permission] = module.default || module;
console.log(`✅ Loaded module for permission: ${permission}`);
} catch (error) {
console.error(`❌ Failed to load module for permission: ${permission}`, error);
}
});
await Promise.allSettled(loadPromises);
console.log(`📦 Loaded ${Object.keys(loadedModules).length} permission-based modules`);
return loadedModules;
}
// 📱 Load device-specific modules
async loadDeviceSpecificModules(): Promise<Record<string, any>> {
console.log('📱 Loading device-specific modules...');
const modules: Record<string, any> = {};
// 📱 Mobile-specific modules
if (this.isMobile()) {
console.log('📱 Loading mobile modules...');
try {
modules.touch = await import('./modules/TouchGesturesModule');
modules.camera = await import('./modules/CameraModule');
modules.geolocation = await import('./modules/GeolocationModule');
} catch (error) {
console.warn('⚠️ Some mobile modules failed to load:', error);
}
}
// 💻 Desktop-specific modules
if (this.isDesktop()) {
console.log('💻 Loading desktop modules...');
try {
modules.keyboard = await import('./modules/KeyboardShortcutsModule');
modules.contextMenu = await import('./modules/ContextMenuModule');
modules.dragDrop = await import('./modules/DragDropModule');
} catch (error) {
console.warn('⚠️ Some desktop modules failed to load:', error);
}
}
// 🖥️ Large screen modules
if (this.isLargeScreen()) {
console.log('🖥️ Loading large screen modules...');
try {
modules.multiPane = await import('./modules/MultiPaneModule');
modules.advancedCharts = await import('./modules/AdvancedChartsModule');
} catch (error) {
console.warn('⚠️ Some large screen modules failed to load:', error);
}
}
console.log(`📦 Loaded ${Object.keys(modules).length} device-specific modules`);
return modules;
}
// 🔍 Device detection utilities
private isMobile(): boolean {
return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}
private isDesktop(): boolean {
return !this.isMobile() && !this.isTablet();
}
private isTablet(): boolean {
return /iPad|Android/i.test(navigator.userAgent) && window.innerWidth > 768;
}
private isLargeScreen(): boolean {
return window.innerWidth > 1200;
}
// 🧠 Intelligent module preloading
async intelligentPreload(): Promise<void> {
console.log('🧠 Starting intelligent preloading...');
// 📊 Analyze user behavior patterns
const userPatterns = this.analyzeUserPatterns();
// 🎯 Preload likely-to-be-used modules
const preloadCandidates = this.getPredictedModules(userPatterns);
console.log('🎯 Preloading predicted modules:', preloadCandidates);
// 🌊 Preload in idle time
if ('requestIdleCallback' in window) {
(window as any).requestIdleCallback(() => {
this.preloadModules(preloadCandidates);
});
} else {
// 🔄 Fallback for browsers without requestIdleCallback
setTimeout(() => {
this.preloadModules(preloadCandidates);
}, 1000);
}
}
// 📊 Analyze user behavior patterns
private analyzeUserPatterns(): {
mostVisitedRoutes: string[];
timeOfDay: string;
deviceType: string;
previousSessions: string[];
} {
// 🎯 This would typically analyze actual user data
return {
mostVisitedRoutes: ['/products', '/profile'],
timeOfDay: new Date().getHours() < 12 ? 'morning' : 'afternoon',
deviceType: this.isMobile() ? 'mobile' : 'desktop',
previousSessions: ['/home', '/products', '/cart']
};
}
// 🎯 Get predicted modules based on patterns
private getPredictedModules(patterns: any): string[] {
const candidates: string[] = [];
// 📈 Based on most visited routes
patterns.mostVisitedRoutes.forEach((route: string) => {
candidates.push(`./pages${route}Page`);
});
// 🕐 Based on time of day
if (patterns.timeOfDay === 'morning') {
candidates.push('./modules/DashboardModule');
} else {
candidates.push('./modules/ReportsModule');
}
// 📱 Based on device type
if (patterns.deviceType === 'mobile') {
candidates.push('./modules/MobileOptimizedModule');
}
return [...new Set(candidates)]; // Remove duplicates
}
// 🔄 Preload modules
private async preloadModules(modulePaths: string[]): Promise<void> {
const preloadPromises = modulePaths.map(async (path) => {
try {
await import(path);
console.log(`✅ Preloaded: ${path}`);
} catch (error) {
console.warn(`⚠️ Failed to preload: ${path}`, error);
}
});
await Promise.allSettled(preloadPromises);
console.log('🔄 Preloading complete');
}
}
// 🎮 Advanced usage example
const advancedDynamicDemo = async (): Promise<void> => {
const smartLoader = SmartModuleLoader.getInstance();
// 🚀 Route-based loading
const homeComponent = await smartLoader.loadRouteComponent('/home');
console.log('Home component loaded:', homeComponent);
// 🎭 Theme loading
const darkTheme = await smartLoader.loadTheme('dark');
console.log('Dark theme loaded:', darkTheme);
// 🌍 Localization loading
const translations = await smartLoader.loadLocalization('en-US');
console.log('Translations loaded:', translations);
// 🔐 Permission-based loading
const adminModules = await smartLoader.loadPermissionBasedModules([
'admin', 'user_management', 'analytics'
]);
console.log('Admin modules loaded:', adminModules);
// 📱 Device-specific loading
const deviceModules = await smartLoader.loadDeviceSpecificModules();
console.log('Device modules loaded:', deviceModules);
// 🧠 Intelligent preloading
await smartLoader.intelligentPreload();
};
💡 Common Dynamic Import Patterns
Let’s explore the most effective patterns for implementing dynamic imports:
// 🌟 Pattern 1: Lazy Route Components
// Perfect for single-page applications with routing
// 📁 Router with lazy loading
class LazyRouter {
private routes = new Map<string, () => Promise<any>>();
// 📝 Register lazy route
registerRoute(path: string, loader: () => Promise<any>): void {
this.routes.set(path, loader);
}
// 🚀 Load route component
async loadRoute(path: string): Promise<any> {
const loader = this.routes.get(path);
if (!loader) {
throw new Error(`Route not found: ${path}`);
}
console.log(`🚀 Loading route: ${path}`);
try {
const component = await loader();
console.log(`✅ Route loaded: ${path}`);
return component.default || component;
} catch (error) {
console.error(`❌ Failed to load route: ${path}`, error);
throw error;
}
}
}
// 🎯 Usage example
const router = new LazyRouter();
// 📝 Register routes with lazy loading
router.registerRoute('/home', () => import('./pages/HomePage'));
router.registerRoute('/about', () => import('./pages/AboutPage'));
router.registerRoute('/products', () => import('./pages/ProductsPage'));
router.registerRoute('/admin', () => import('./pages/AdminPage'));
// 🚀 Load route when needed
const handleNavigation = async (path: string) => {
try {
const component = await router.loadRoute(path);
// Render component
} catch (error) {
// Handle error
}
};
// 🌟 Pattern 2: Feature Flag Driven Loading
// Load modules based on feature toggles
class FeatureFlagLoader {
private featureFlags = new Map<string, boolean>();
// 🎯 Set feature flag
setFeature(flag: string, enabled: boolean): void {
this.featureFlags.set(flag, enabled);
}
// 🔍 Check if feature is enabled
isFeatureEnabled(flag: string): boolean {
return this.featureFlags.get(flag) || false;
}
// 🚀 Load module if feature is enabled
async loadIfEnabled(flag: string, modulePath: string): Promise<any | null> {
if (this.isFeatureEnabled(flag)) {
console.log(`✅ Feature '${flag}' enabled, loading: ${modulePath}`);
return await import(modulePath);
} else {
console.log(`❌ Feature '${flag}' disabled, skipping: ${modulePath}`);
return null;
}
}
// 📦 Load multiple feature modules
async loadFeatureModules(
features: Record<string, string>
): Promise<Record<string, any>> {
const loadedModules: Record<string, any> = {};
const loadPromises = Object.entries(features).map(async ([flag, modulePath]) => {
const module = await this.loadIfEnabled(flag, modulePath);
if (module) {
loadedModules[flag] = module;
}
});
await Promise.allSettled(loadPromises);
return loadedModules;
}
}
// 🎯 Usage example
const featureLoader = new FeatureFlagLoader();
// 🎚️ Configure features
featureLoader.setFeature('beta_dashboard', true);
featureLoader.setFeature('experimental_charts', false);
featureLoader.setFeature('advanced_analytics', true);
// 📦 Load feature modules
const features = await featureLoader.loadFeatureModules({
'beta_dashboard': './features/BetaDashboard',
'experimental_charts': './features/ExperimentalCharts',
'advanced_analytics': './features/AdvancedAnalytics'
});
// 🌟 Pattern 3: Progressive Loading
// Load modules progressively based on user interaction
class ProgressiveLoader {
private loadQueue: Array<{
priority: number;
loader: () => Promise<any>;
name: string;
}> = [];
private isLoading = false;
// 📝 Add module to load queue
addToQueue(
name: string,
loader: () => Promise<any>,
priority: number = 1
): void {
this.loadQueue.push({ name, loader, priority });
// 🔀 Sort by priority (higher priority first)
this.loadQueue.sort((a, b) => b.priority - a.priority);
}
// 🚀 Start progressive loading
async startProgressiveLoading(): Promise<void> {
if (this.isLoading) {
console.log('⏳ Progressive loading already in progress');
return;
}
this.isLoading = true;
console.log(`🚀 Starting progressive loading of ${this.loadQueue.length} modules`);
while (this.loadQueue.length > 0) {
const item = this.loadQueue.shift()!;
try {
console.log(`⚡ Loading: ${item.name} (priority: ${item.priority})`);
await item.loader();
console.log(`✅ Loaded: ${item.name}`);
// 🌬️ Yield to main thread between loads
await this.yieldToMainThread();
} catch (error) {
console.error(`❌ Failed to load: ${item.name}`, error);
}
}
this.isLoading = false;
console.log('✅ Progressive loading complete');
}
// 🌬️ Yield to main thread
private yieldToMainThread(): Promise<void> {
return new Promise(resolve => setTimeout(resolve, 0));
}
// ⏸️ Pause loading
pauseLoading(): void {
this.isLoading = false;
console.log('⏸️ Progressive loading paused');
}
// 🧹 Clear load queue
clearQueue(): void {
this.loadQueue = [];
console.log('🧹 Load queue cleared');
}
}
// 🎯 Usage example
const progressiveLoader = new ProgressiveLoader();
// 📝 Add modules to queue with priorities
progressiveLoader.addToQueue(
'Critical Analytics',
() => import('./analytics/CriticalMetrics'),
10 // High priority
);
progressiveLoader.addToQueue(
'Background Sync',
() => import('./sync/BackgroundSync'),
5 // Medium priority
);
progressiveLoader.addToQueue(
'Non-Critical Features',
() => import('./features/NonCritical'),
1 // Low priority
);
// 🚀 Start loading when app is ready
document.addEventListener('DOMContentLoaded', () => {
progressiveLoader.startProgressiveLoading();
});
// 🌟 Pattern 4: Conditional Module Loading
// Load different modules based on runtime conditions
class ConditionalModuleLoader {
// 🌍 Load based on environment
async loadEnvironmentModule(): Promise<any> {
const environment = process.env.NODE_ENV || 'production';
console.log(`🌍 Loading module for environment: ${environment}`);
switch (environment) {
case 'development':
return await import('./config/DevelopmentConfig');
case 'staging':
return await import('./config/StagingConfig');
case 'production':
return await import('./config/ProductionConfig');
case 'test':
return await import('./config/TestConfig');
default:
console.warn(`⚠️ Unknown environment: ${environment}, falling back to production`);
return await import('./config/ProductionConfig');
}
}
// 📱 Load based on device capabilities
async loadDeviceCapabilityModules(): Promise<Record<string, any>> {
const modules: Record<string, any> = {};
// 📷 Camera support
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
console.log('📷 Camera supported, loading camera module');
modules.camera = await import('./device/CameraModule');
}
// 🌍 Geolocation support
if (navigator.geolocation) {
console.log('🌍 Geolocation supported, loading location module');
modules.geolocation = await import('./device/GeolocationModule');
}
// 💾 Storage support
if ('localStorage' in window) {
console.log('💾 LocalStorage supported, loading storage module');
modules.localStorage = await import('./storage/LocalStorageModule');
}
// 🗄️ IndexedDB support
if ('indexedDB' in window) {
console.log('🗄️ IndexedDB supported, loading database module');
modules.indexedDB = await import('./storage/IndexedDBModule');
}
// 👷 Service Worker support
if ('serviceWorker' in navigator) {
console.log('👷 Service Worker supported, loading PWA module');
modules.serviceWorker = await import('./pwa/ServiceWorkerModule');
}
// 🎨 WebGL support
const canvas = document.createElement('canvas');
const webglContext = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (webglContext) {
console.log('🎨 WebGL supported, loading graphics module');
modules.webgl = await import('./graphics/WebGLModule');
}
return modules;
}
// 🔐 Load based on user role
async loadRoleBasedModules(userRole: string): Promise<Record<string, any>> {
console.log(`🔐 Loading modules for role: ${userRole}`);
const modules: Record<string, any> = {};
// 👥 Common modules for all users
modules.profile = await import('./modules/ProfileModule');
modules.settings = await import('./modules/SettingsModule');
// 🎯 Role-specific modules
switch (userRole) {
case 'admin':
modules.userManagement = await import('./admin/UserManagementModule');
modules.systemSettings = await import('./admin/SystemSettingsModule');
modules.analytics = await import('./admin/AnalyticsModule');
break;
case 'moderator':
modules.contentModeration = await import('./moderator/ContentModerationModule');
modules.reportManagement = await import('./moderator/ReportManagementModule');
break;
case 'premium':
modules.premiumFeatures = await import('./premium/PremiumFeaturesModule');
modules.advancedAnalytics = await import('./premium/AdvancedAnalyticsModule');
break;
case 'basic':
modules.basicFeatures = await import('./basic/BasicFeaturesModule');
break;
default:
console.warn(`⚠️ Unknown role: ${userRole}, loading basic modules`);
modules.basicFeatures = await import('./basic/BasicFeaturesModule');
}
console.log(`📦 Loaded ${Object.keys(modules).length} role-based modules`);
return modules;
}
// 🌐 Load based on browser capabilities
async loadBrowserSpecificModules(): Promise<Record<string, any>> {
const modules: Record<string, any> = {};
// 🔍 Detect browser
const userAgent = navigator.userAgent;
if (userAgent.includes('Chrome')) {
console.log('🎯 Chrome detected, loading Chrome-specific modules');
modules.chrome = await import('./browser/ChromeSpecificModule');
}
if (userAgent.includes('Firefox')) {
console.log('🦊 Firefox detected, loading Firefox-specific modules');
modules.firefox = await import('./browser/FirefoxSpecificModule');
}
if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) {
console.log('🧭 Safari detected, loading Safari-specific modules');
modules.safari = await import('./browser/SafariSpecificModule');
}
if (userAgent.includes('Edge')) {
console.log('🌐 Edge detected, loading Edge-specific modules');
modules.edge = await import('./browser/EdgeSpecificModule');
}
// 📱 Mobile browser detection
if (/Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)) {
console.log('📱 Mobile browser detected, loading mobile modules');
modules.mobile = await import('./browser/MobileBrowserModule');
}
return modules;
}
}
// 🎯 Usage example
const conditionalLoader = new ConditionalModuleLoader();
// 🚀 Load all conditional modules
const initializeApp = async () => {
console.log('🚀 Initializing app with conditional loading...');
const [
envModule,
deviceModules,
roleModules,
browserModules
] = await Promise.all([
conditionalLoader.loadEnvironmentModule(),
conditionalLoader.loadDeviceCapabilityModules(),
conditionalLoader.loadRoleBasedModules('admin'),
conditionalLoader.loadBrowserSpecificModules()
]);
console.log('✅ App initialization complete');
console.log('Environment config:', envModule);
console.log('Device modules:', Object.keys(deviceModules));
console.log('Role modules:', Object.keys(roleModules));
console.log('Browser modules:', Object.keys(browserModules));
};
initializeApp();
🎉 Conclusion
Congratulations! You’ve mastered the power of dynamic imports! ⚡
🎯 What You’ve Learned
- ⚡ Dynamic Import Syntax: Runtime module loading with import() function
- 🚀 Lazy Loading: Loading modules only when needed for better performance
- 🎯 Conditional Loading: Smart module loading based on runtime conditions
- 📦 Code Splitting: Breaking applications into smaller, loadable chunks
- 🧠 Intelligent Preloading: Predictive loading strategies for optimal UX
🚀 Key Benefits
- ⚡ Faster Initial Load: Reduced bundle size and faster startup times
- 💾 Better Memory Usage: Load modules only when needed
- 📱 Responsive Experience: Progressive loading without blocking the UI
- 🎯 Smart Optimization: Load exactly what users need, when they need it
- 🔧 Flexible Architecture: Adaptable loading strategies for different scenarios
🔥 Best Practices Recap
- ⚡ Load on Demand: Only load modules when they’re actually needed
- 🎯 Implement Fallbacks: Always have error handling and fallback strategies
- 📦 Cache Wisely: Implement intelligent caching to avoid redundant loads
- 🧠 Preload Strategically: Use idle time to preload likely-needed modules
- 📊 Monitor Performance: Track loading metrics and optimize accordingly
You’re now equipped to create lightning-fast applications that load efficiently and provide excellent user experiences through smart dynamic loading! 🌟
Happy coding, and may your modules always load exactly when needed! ⚡✨