react-native-pdf-jsi includes a powerful 30-day persistent local cache system that can dramatically reduce PDF loading times from seconds to milliseconds! Most developers don't know about this hidden gem.
- PDF data is stored in device's persistent storage
- 30-day TTL (Time To Live) with automatic cleanup
- Intelligent LRU (Least Recently Used) eviction
- Automatic background cleanup every 24 hours
- 80x faster than downloading from network
- Zero network requests for cached PDFs
- Offline capability - works without internet
- Memory optimized with smart cache management
| Scenario | Without Cache | With Local Cache | Improvement |
|---|---|---|---|
| Large PDF (50MB) | 8-12 seconds | 0.1-0.5 seconds | 20-120x faster |
| Medium PDF (10MB) | 2-4 seconds | 0.05-0.2 seconds | 10-80x faster |
| Small PDF (1MB) | 0.5-1 second | 0.01-0.05 seconds | 10-100x faster |
| Offline Access | ❌ Not possible | ✅ Instant access | ∞x better |
import Pdf from 'react-native-pdf-jsi';
// PDFs are automatically cached when loaded
<Pdf
source={{ uri: 'https://example.com/large-document.pdf' }}
style={{ flex: 1 }}
// Cache is automatically enabled - no extra code needed!
onLoadComplete={(numberOfPages) => {
console.log(`PDF loaded and cached: ${numberOfPages} pages`);
}}
/>import { PDFJSI } from 'react-native-pdf-jsi';
// Store PDF in cache manually
const storePDFInCache = async (base64Data) => {
try {
const result = await PDFJSI.storePDFNative(base64Data, {
ttl: 30 * 24 * 60 * 60 * 1000, // 30 days in milliseconds
enableValidation: true,
enableCompression: true
});
console.log('PDF cached with ID:', result.cacheId);
return result.cacheId;
} catch (error) {
console.error('Cache storage failed:', error);
}
};
// Load PDF from cache
const loadPDFFromCache = async (cacheId) => {
try {
const result = await PDFJSI.loadPDFNative(cacheId);
console.log('PDF loaded from cache:', result.filePath);
return result.filePath;
} catch (error) {
console.error('Cache load failed:', error);
}
};
// Check if cache is valid
const isCacheValid = async (cacheId) => {
try {
const result = await PDFJSI.isValidCacheNative(cacheId);
return result.isValid;
} catch (error) {
return false;
}
};import { usePDFJSI } from 'react-native-pdf-jsi';
const MyPDFViewer = () => {
const {
lazyLoadPages,
smartCacheFrequentPages,
getCacheMetrics
} = usePDFJSI({
autoInitialize: true,
enableCaching: true,
maxCacheSize: 500 // 500MB cache limit
});
const handlePDFLoad = async (pdfId) => {
// Pre-cache frequently accessed pages
const frequentPages = [1, 2, 10, 50, 100];
await smartCacheFrequentPages(pdfId, frequentPages);
// Get cache statistics
const metrics = await getCacheMetrics();
console.log('Cache stats:', metrics);
};
return (
<Pdf
source={{ uri: 'https://example.com/document.pdf' }}
onLoadComplete={handlePDFLoad}
style={{ flex: 1 }}
/>
);
};// Pre-cache PDFs during app initialization
useEffect(() => {
const preCachePDFs = async () => {
const criticalPDFs = [
'https://example.com/user-manual.pdf',
'https://example.com/terms-of-service.pdf',
'https://example.com/help-guide.pdf'
];
for (const pdfUrl of criticalPDFs) {
try {
// Download and cache PDF
const response = await fetch(pdfUrl);
const base64Data = await response.text();
await storePDFInCache(base64Data);
} catch (error) {
console.warn(`Failed to pre-cache ${pdfUrl}:`, error);
}
}
};
preCachePDFs();
}, []);// Monitor cache usage and cleanup when needed
const manageCache = async () => {
const stats = await PDFJSI.getNativeCacheStats();
console.log(`Cache Stats:
- Total Files: ${stats.totalFiles}
- Total Size: ${stats.totalSizeFormatted}
- Hit Rate: ${(stats.hitRate * 100).toFixed(1)}%
- Average Load Time: ${stats.averageLoadTimeMs.toFixed(2)}ms`);
// Clear cache if it's too large
if (stats.totalSize > 400 * 1024 * 1024) { // 400MB
await PDFJSI.clearNativeCache();
console.log('Cache cleared due to size limit');
}
};const loadPDFWithFallback = async (url) => {
try {
// Try to load from cache first
const cacheId = generateCacheId(url);
const isValid = await isCacheValid(cacheId);
if (isValid) {
console.log('Loading from cache...');
return await loadPDFFromCache(cacheId);
} else {
console.log('Cache miss, downloading...');
const response = await fetch(url);
const base64Data = await response.text();
const newCacheId = await storePDFInCache(base64Data);
return await loadPDFFromCache(newCacheId);
}
} catch (error) {
console.error('PDF loading failed:', error);
throw error;
}
};- Cache Location: External files directory for persistence
- Maximum Cache Size: 500MB with automatic LRU eviction
- Background Cleanup: Every 24 hours
- File Protection: Atomic writes with sync to disk
- Cache Location: Application documents directory
- File Protection: Complete until first user authentication
- Background Cleanup: Scheduled cleanup tasks
- Memory Management: Automatic memory pressure handling
// Get detailed cache information
const debugCache = async () => {
try {
// Test cache functionality
const testResult = await PDFJSI.testNativeCache();
console.log('Cache Test Result:', testResult);
// Get cache statistics
const stats = await PDFJSI.getNativeCacheStats();
console.log('Cache Statistics:', stats);
// Check JSI availability
const jsiStatus = await PDFJSI.checkJSIAvailability();
console.log('JSI Status:', jsiStatus);
} catch (error) {
console.error('Cache debugging failed:', error);
}
};// Wrong: Disabling cache
<Pdf
source={{ uri: pdfUrl }}
enableCaching={false} // This disables the performance boost!
/>
// Wrong: Not handling cache errors
const loadPDF = async () => {
const result = await PDFJSI.loadPDFNative(cacheId);
// No error handling - app will crash if cache fails
};// Correct: Let cache work automatically
<Pdf
source={{ uri: pdfUrl }}
// Cache is enabled by default - no configuration needed!
/>
// Correct: Proper error handling
const loadPDF = async () => {
try {
const result = await PDFJSI.loadPDFNative(cacheId);
return result.filePath;
} catch (error) {
console.warn('Cache miss, falling back to network:', error);
// Fallback to network download
return await downloadFromNetwork();
}
};- User opens PDF → 8-12 second wait
- Poor user experience
- High data usage
- No offline capability
- Users abandon the app
- User opens PDF → 0.1-0.5 second load
- Excellent user experience
- Minimal data usage
- Full offline capability
- Users love the app
The local cache system in react-native-pdf-jsi is a game-changer that most developers don't know about. By leveraging this 30-day persistent cache:
- 20-120x faster PDF loading
- Zero network requests for cached content
- Full offline capability
- Automatic management with LRU eviction
- Cross-platform optimization
Start using it today and watch your app's performance soar! 🚀
This pro tip can transform your app's user experience from frustratingly slow to lightning-fast. The cache system works automatically - you just need to know it exists and how to leverage it properly.