Skip to content

Latest commit

 

History

History
310 lines (253 loc) · 8.43 KB

File metadata and controls

310 lines (253 loc) · 8.43 KB

🚀 Pro Tip: Local Cache System for Lightning-Fast PDF Loading

⚡ The Game-Changing Feature You're Missing

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.

🎯 How It Works

First Load: PDF is downloaded and cached locally

  • 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

Subsequent Loads: Instant access from local cache

  • 80x faster than downloading from network
  • Zero network requests for cached PDFs
  • Offline capability - works without internet
  • Memory optimized with smart cache management

📊 Performance Impact

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

🔧 Implementation

Automatic Caching (Recommended)

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`);
  }}
/>

Manual Cache Management

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;
  }
};

Advanced Cache Configuration

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 }}
    />
  );
};

🎯 Pro Tips for Maximum Performance

1. Pre-cache Critical PDFs

// 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();
}, []);

2. Smart Cache Management

// 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');
  }
};

3. Offline-First Architecture

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;
  }
};

📱 Platform-Specific Optimizations

Android

  • 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

iOS

  • Cache Location: Application documents directory
  • File Protection: Complete until first user authentication
  • Background Cleanup: Scheduled cleanup tasks
  • Memory Management: Automatic memory pressure handling

🔍 Cache Monitoring & Debugging

// 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);
  }
};

🚨 Common Mistakes to Avoid

Don't Do This

// 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
};

Do This Instead

// 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();
  }
};

📊 Real-World Impact

Before (No Cache)

  • User opens PDF → 8-12 second wait
  • Poor user experience
  • High data usage
  • No offline capability
  • Users abandon the app

After (With Cache)

  • User opens PDF → 0.1-0.5 second load
  • Excellent user experience
  • Minimal data usage
  • Full offline capability
  • Users love the app

🎉 Summary

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.