Skip to main content

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:

  1. Client-side Cache - LRU cache in the SDK (500 entries, 1-hour TTL)
  2. Server-side Cache - Redis cache on our API servers (24-hour TTL)
  3. 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

Need Help?

Questions about caching strategies?

  • Check our troubleshooting guide
  • Join our Discord for performance discussions
  • Contact support for enterprise caching solutions