Caching Strategies
Learn how to optimize performance using LiveI18n's intelligent caching system and implement your own caching strategies.
Overview
LiveI18n uses a multi-layer caching approach to ensure lightning-fast translation delivery:
- Client-side Cache - LRU cache in the SDK (500 entries, 1-hour TTL)
- Server-side Cache - Redis cache on our API servers (24-hour TTL)
- CDN Cache - Global edge caching for maximum performance (coming soon)
Client-Side Caching
How It Works
The React SDK includes an intelligent LRU (Least Recently Used) cache:
// Automatic caching - no configuration needed
<LiveText>Welcome to our app!</LiveText> // API call
<LiveText>Welcome to our app!</LiveText> // Cache hit (instant)
Cache Key Generation
LiveI18n uses canonical cache keys to maximize cache efficiency:
// These all generate the same cache key (normalized):
<LiveText context="greeting">Hello</LiveText>
<LiveText context="Greeting">Hello</LiveText>
<LiveText context="greeting ">Hello</LiveText> // Extra space ignored
// These generate different cache keys:
<LiveText context="greeting">Hello</LiveText>
<LiveText context="farewell">Hello</LiveText>
<LiveText tone="friendly" context="greeting">Hello</LiveText>
Cache Performance Monitoring
Monitor cache performance in development:
// Enable debug mode to see cache stats
initializeLiveI18n({
// ... other config
debug: process.env.NODE_ENV === 'development'
});
// Check browser console for:
// - Cache hit/miss ratios
// - Memory usage
// - Performance metrics
Server-Side Caching
Redis Cache
Our API servers use Redis for distributed caching:
- 24-hour TTL for stable translations
- Automatic invalidation for content updates
Cache Warming
Pre-populate cache for better performance:
// Warm cache with common translations
const commonTexts = [
'Welcome',
'Sign In',
'Sign Up',
'Contact Us',
'About',
'Home'
];
// These will be cached for future use
commonTexts.forEach(text => {
// Render off-screen to trigger caching
const element = document.createElement('div');
element.style.display = 'none';
ReactDOM.render(<LiveText>{text}</LiveText>, element);
});
Optimization Strategies
1. Consistent Text Usage
// ✅ Good - creates single cache entry
const BUTTON_TEXT = 'Add to Cart';
<LiveText context="shopping">{BUTTON_TEXT}</LiveText>
<LiveText context="shopping">{BUTTON_TEXT}</LiveText>
// ❌ Avoid - creates multiple cache entries
<LiveText context="shopping">Add to Cart</LiveText>
<LiveText context="shopping">Add To Cart</LiveText> // Different case
2. Stable Context and Tone
// ✅ Good - consistent parameters
const CONTEXT = 'product page';
const TONE = 'marketing';
<LiveText context={CONTEXT} tone={TONE}>Special Offer!</LiveText>
<LiveText context={CONTEXT} tone={TONE}>Limited Time!</LiveText>
// ❌ Avoid - dynamic parameters that change frequently
<LiveText context={`product-${product.id}`}>Add to Cart</LiveText>
3. Batch Similar Translations
// ✅ Good - similar context allows batch processing
const navigationItems = ['Home', 'About', 'Products', 'Contact'];
{navigationItems.map(item => (
<LiveText key={item} context="navigation">
{item}
</LiveText>
))}
4. Avoid Cache Pollution
// ❌ Avoid - creates too many cache entries
<LiveText>User {userId} logged in</LiveText> // Different for each user
// ✅ Better - separate static and dynamic content
<LiveText context="status">User logged in:</LiveText> {username}
Advanced Caching Techniques
Pre-loading Translations
Pre-load translations for better UX:
import { useMemo, useEffect } from 'react';
function PreloadTranslations({ texts }) {
const cachedTexts = useMemo(() => {
// Pre-render texts to trigger caching
return texts.map(text => (
<div key={text} style={{ display: 'none' }}>
<LiveText>{text}</LiveText>
</div>
));
}, [texts]);
return <div>{cachedTexts}</div>;
}
// Usage - pre-load common UI text
function App() {
return (
<div>
<PreloadTranslations texts={[
'Loading...',
'Error occurred',
'Success!',
'Please wait'
]} />
{/* Rest of your app */}
</div>
);
}
Route-Based Cache Warming
Pre-load translations for the next likely page:
import { useEffect } from 'react';
import { useRouter } from 'next/router';
function useRouteBasedCaching() {
const router = useRouter();
useEffect(() => {
const preloadTexts = (route) => {
const routeTexts = {
'/products': ['Add to Cart', 'Product Details', 'Price'],
'/checkout': ['Checkout', 'Payment', 'Shipping'],
'/profile': ['Profile', 'Settings', 'Account']
};
return routeTexts[route] || [];
};
// Pre-cache likely next page content
const currentRoute = router.pathname;
const likelyNextRoutes = getLikelyNextRoutes(currentRoute);
likelyNextRoutes.forEach(route => {
const texts = preloadTexts(route);
texts.forEach(text => {
// Trigger caching without rendering
cachePrefetch(text);
});
});
}, [router.pathname]);
}
Component-Level Caching
Implement component-level caching for complex translations:
import { memo, useMemo } from 'react';
const CachedTranslation = memo(function CachedTranslation({
text,
context,
tone,
dependencies = []
}) {
const memoizedTranslation = useMemo(() => (
<LiveText context={context} tone={tone}>
{text}
</LiveText>
), [text, context, tone, ...dependencies]);
return memoizedTranslation;
});
// Usage - only re-translates when dependencies change
function ProductCard({ product, userLanguage }) {
return (
<div>
<CachedTranslation
text={product.description}
context="product-description"
tone="marketing"
dependencies={[userLanguage]} // Re-translate when language changes
/>
</div>
);
}
Cache Management
Manual Cache Control
Clear cache when needed:
// Clear all cached translations (browser refresh equivalent)
localStorage.removeItem('livei18n_cache');
// Or implement custom cache clearing
import { clearCache } from '@livei18n/react-sdk';
function AdminPanel() {
const handleClearCache = () => {
clearCache();
alert('Cache cleared successfully');
};
return (
<button onClick={handleClearCache}>
Clear Translation Cache
</button>
);
}
Cache Statistics
Monitor cache performance:
import { getCacheStats } from '@livei18n/react-sdk';
function CacheStats() {
const [stats, setStats] = useState(null);
useEffect(() => {
const updateStats = () => {
setStats(getCacheStats());
};
updateStats();
const interval = setInterval(updateStats, 5000);
return () => clearInterval(interval);
}, []);
if (!stats) return null;
return (
<div className="cache-stats">
<h3>Cache Performance</h3>
<p>Hit Rate: {stats.hitRate}%</p>
<p>Entries: {stats.size}/{stats.maxSize}</p>
<p>Memory Usage: {stats.memoryUsage}KB</p>
</div>
);
}
Performance Metrics
Expected Performance
With proper caching:
- Cache Hits: 1ms response time
- Cache Misses: 100-500ms response time
- Memory Usage: ~10MB for 1000 cached translations
- Hit Ratio: 85-95% for typical applications
Measuring Performance
// Performance monitoring
const measureTranslationPerformance = async (text, options) => {
const start = performance.now();
const result = await translate(text, options);
const end = performance.now();
const duration = end - start;
console.log(`Translation took ${duration}ms`, {
text,
cached: duration < 10, // Likely cached if very fast
performance: duration < 100 ? 'excellent' : 'good'
});
return result;
};
Best Practices Summary
Do's ✅
- Use consistent text, context, and tone
- Pre-load common translations
- Monitor cache hit rates
- Implement route-based pre-caching
- Use stable cache keys
Don'ts ❌
- Don't include dynamic data in translatable text
- Don't change context/tone frequently for the same text
- Don't disable caching unless necessary
- Don't translate technical terms or proper nouns
- Don't ignore cache performance metrics
Troubleshooting
Low Cache Hit Rates
Symptoms: Frequent API calls, slow performance Solutions:
- Check for dynamic content in translations
- Verify consistent context/tone usage
- Monitor cache key generation
High Memory Usage
Symptoms: Browser slowdown, memory warnings Solutions:
- Reduce cache size limit
- Implement more aggressive TTL
- Clear cache periodically
Stale Translations
Symptoms: Old translations showing after content updates Solutions:
- Clear client cache after deployments
- Implement cache versioning
- Use shorter TTL for frequently changing content
Testing Cache Behavior
Development Testing
// Test cache behavior in development
const testCachePerformance = () => {
const texts = ['Hello', 'Welcome', 'Goodbye'];
texts.forEach(async (text, index) => {
console.time(`Translation ${index + 1}`);
// First call - should be slow (cache miss)
await translate(text);
console.timeEnd(`Translation ${index + 1} - First`);
console.time(`Translation ${index + 1} - Second`);
// Second call - should be fast (cache hit)
await translate(text);
console.timeEnd(`Translation ${index + 1} - Second`);
});
};
Production Monitoring
// Monitor cache performance in production
const trackCacheMetrics = () => {
const metrics = {
hits: 0,
misses: 0,
totalRequests: 0
};
// Override translate function to track metrics
const originalTranslate = window.LiveI18n.translate;
window.LiveI18n.translate = async (...args) => {
const start = performance.now();
const result = await originalTranslate.apply(this, args);
const duration = performance.now() - start;
metrics.totalRequests++;
if (duration < 10) {
metrics.hits++;
} else {
metrics.misses++;
}
// Send metrics to analytics
if (metrics.totalRequests % 100 === 0) {
analytics.track('cache_performance', {
hitRate: (metrics.hits / metrics.totalRequests) * 100,
avgDuration: duration
});
}
return result;
};
};
Next Steps
- Learn best practices - Overall optimization strategies
- Try the demo - Test caching behavior
- Review React SDK advanced features - Advanced caching options
Need Help?
Questions about caching strategies?
- Check our troubleshooting guide
- Join our Discord for performance discussions
- Contact support for enterprise caching solutions