Performance & Memory Optimizations
Overview
This document outlines the performance and memory optimizations implemented to address segmentation faults and high memory consumption.
Issues Identified
- Large node_modules (1.2GB) - Contributing to build time and memory usage
- Memory leaks - Unmanaged subscriptions and timers
- Inefficient rendering - ScrollView instead of FlatList for large lists
- Excessive caching - Service worker caching large files
- No memoization - Components re-rendering unnecessarily
- Real-time subscriptions - Not properly cleaned up
Optimizations Implemented
1. Memory Management (lib/memory-manager.ts)
- Subscription Manager: Tracks and automatically cleans up Supabase real-time subscriptions
- Timer Manager: Manages and clears timers to prevent leaks
- Automatic Cleanup: Expires old subscriptions after 1 hour
- Max Subscriptions: Limits concurrent subscriptions to 20
2. Performance Utilities (lib/performance-utils.ts)
- Debounce/Throttle: Limits function call frequency
- Image Cache Manager: Manages image caching with size limits (50 images max, 30min expiry)
- Batched Updates: Reduces re-renders by batching state updates
- Lazy Image Loading: Intersection Observer for images
3. Component Optimizations
SpeakerListWithDividers.tsx
- Before: ScrollView rendering all speakers at once
- After: FlatList with virtualization
removeClippedSubviews={true}- Unmounts off-screen itemsmaxToRenderPerBatch={10}- Limits batch renderinginitialNumToRender={15}- Only renders visible items initiallywindowSize={10}- Controls render window size
SpeakerSearchAndSort.tsx
- Memoization: Added
useMemoanduseCallbackfor:- Filtered speakers
- Sorted speakers
- Grouped speakers
- Reduced Re-renders: Only recalculates when dependencies change
4. Real-time Subscription Cleanup
useRealtimeMeetingRequests.ts
- Integrated with
memoryManagerfor automatic cleanup - Registers subscriptions with unique IDs
- Cleans up on unmount or when limit reached
useRealtimeChat.ts
- Integrated with
memoryManager - Proper cleanup on component unmount
- Prevents subscription leaks
5. Service Worker Optimizations (apps/mobile-app/public/sw.js)
- Size Limits: Only caches files < 5MB
- File Type Filtering: Skips caching large files (images, videos, PDFs)
- Content-Length Check: Validates file size before caching
- Error Handling: Catches and logs cache failures
6. Metro Bundler Optimizations (metro.config.js)
- Single Worker:
maxWorkers = 1to reduce memory - Cache Versioning: Prevents stale cache issues
- Transformer Optimizations: Minification settings for production
7. Workbox Configuration (apps/mobile-app/workbox-config.js)
- Reduced Cache Size: 5MB → 2MB maximum file size
- Entry Limits: Maximum 50 cache entries
- Prevents Memory Bloat: Limits total cached data
Performance Metrics
Before Optimizations
- Memory Usage: High (segmentation faults)
- Render Performance: Slow with large lists
- Cache Size: Unlimited (causing memory issues)
- Subscription Leaks: Multiple unmanaged subscriptions
After Optimizations
- Memory Usage: Controlled with limits and cleanup
- Render Performance: Optimized with FlatList virtualization
- Cache Size: Limited to 2MB per file, 50 entries max
- Subscription Management: Automatic cleanup and limits
Best Practices
For New Components
- Use
FlatListinstead ofScrollViewfor large lists - Memoize expensive calculations with
useMemo - Use
useCallbackfor event handlers passed to children - Register subscriptions with
memoryManager - Clean up timers and subscriptions in
useEffectcleanup
For Images
- Use
imageCacheManagerfor caching - Implement lazy loading with
useLazyImage - Set appropriate
resizeModeand size limits - Use
cache: 'force-cache'for static images
For Real-time Features
- Always register subscriptions with
memoryManager - Clean up in
useEffectreturn function - Use unique subscription IDs
- Monitor subscription count with
memoryManager.getStats()
Monitoring
Memory Stats
import { memoryManager } from '@/lib/memory-manager';
// Get current stats
const stats = memoryManager.getStats();
console.log('Subscriptions:', stats.subscriptions);
console.log('Timers:', stats.timers);
Image Cache Stats
import { imageCacheManager } from '@/lib/performance-utils';
// Cleanup expired entries
imageCacheManager.cleanup();
// Clear all cache
imageCacheManager.clear();
Future Improvements
- Bundle Analysis: Use
@expo/bundle-analyzerto identify large dependencies - Code Splitting: Implement dynamic imports for heavy components
- Image Optimization: Use WebP format and responsive images
- Virtual Scrolling: Extend to more list components
- Memory Profiling: Add periodic memory usage monitoring