How Offline Mode Works
The app uses a preloading and caching strategy to ensure smooth navigation without requiring an internet connection.Image Preloading
Mushaf page images are preloaded using theuseImagePreloader hook (hooks/useImagePreloader.ts).
Predictive Preloading
The app automatically preloads nearby pages:
- Current page
- Previous page (currentPage - 1)
- Next page (currentPage + 1)
- Next next page (currentPage + 2)
Preloading Logic
The preloader follows this strategy:Preloading happens automatically as you navigate. You don’t need to manually download pages.
Caching Strategy
Smart Cache Management
The app uses an intelligent caching system:- Parallel Downloads: All 4 pages (current, -1, +1, +2) are downloaded in parallel using
Promise.all() - Duplicate Prevention: Already preloaded pages are tracked in
preloadedPagesRefto avoid re-downloading - Cache Limit: Only pages within the current viewing window are kept in cache
- Automatic Cleanup: Pages far from the current position are removed from cache to save memory
Cache Retention
Pages are kept in cache only if they are:- The current page, OR
- Within 1 page before the current page, OR
- Within 2 pages after the current page
- Smooth backward navigation (1 page cached)
- Very smooth forward navigation (2 pages cached)
- Limited memory footprint
The cache automatically updates as you navigate. Old pages are removed and new pages are preloaded based on your current position.
Storage Implementation
Asset Storage
Mushaf images are stored as bundled assets using Expo’s Asset system:- Image Maps:
constants/imagesMapHafs.tsandconstants/imagesMapWarsh.ts - Asset Loading: Uses
Asset.fromModule()to reference images - Download API: Uses
asset.downloadAsync()to ensure images are cached
Data Storage
App data is stored using MMKV for fast, synchronous access: Storage Configuration (utils/storage/createStorage.ts):
What’s Stored Offline
All app data is stored locally:- User Preferences
- Reading Progress
- Quran Metadata
- Current reading position (
currentSavedPage) - Theme settings (via system color scheme)
- Mushaf contrast level (
mushafContrast) - Flip sound preference (
flipSound) - Selected Riwaya (
mushafRiwaya) - Menu states (
bottomMenuState,topMenuState)
Riwaya-Specific Caching
The preloader adapts to the selected Riwaya:- Hafs: Uses Hafs-specific page images (typically 604 pages)
- Warsh: Uses Warsh-specific page images (page count may differ)
When you change Riwaya, the app will need to download the new set of Mushaf images. Previously cached images from the other Riwaya are not automatically deleted.
Performance Optimizations
Efficient Loading
- Check Before Download: The preloader checks
asset.downloadedbefore downloading - Parallel Processing: Multiple pages download simultaneously
- Ref-Based Tracking: Uses
useRefto avoid re-renders during cache updates - Set-Based Lookup: Uses
Setfor O(1) cache lookup performance
Memory Management
- Limited Window: Only 4 pages in memory at once
- Automatic Cleanup: Old pages removed as you navigate
- No Manual Management: Everything handled automatically
Error Handling
The preloader includes error handling:Offline-First Design
Open Mushaf Native is built with offline-first principles:- No API Calls: All Quran data is bundled with the app
- Local Assets: Mushaf images are local assets, not remote URLs
- Synchronous Storage: MMKV provides instant read/write without async overhead
- No Network Dependency: The app works identically online and offline
Once the app is installed and the initial assets are downloaded, you never need an internet connection to use Open Mushaf Native.
Storage Size
Expected storage usage:- App Bundle: Includes all Mushaf images for the default Riwaya
- MMKV Storage: Typically < 1 MB for all user data and preferences
- Asset Cache: Images are cached as needed, with only nearby pages kept in memory
- Selected Riwaya (Hafs vs. Warsh)
- Image quality and compression
- Number of pages (604 for Hafs)