Caching improves performance significantly. This article covers caching strategies and implementation.
Introduction
Caching provides:
- Faster load times
- Reduced bandwidth
- Lower server load
- Better scalability
- Improved user experience
Caching Layers
Browser Caching
// ✅ Good: HTTP caching headers
app.get('/api/users/:id', (req, res) => {
res.set('Cache-Control', 'public, max-age=3600');
res.set('ETag', '"abc123"');
res.json(user);
});
// ✅ Good: Service Worker caching
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// ✅ Good: LocalStorage caching
localStorage.setItem('user', JSON.stringify(user));
const cached = JSON.parse(localStorage.getItem('user'));
Server Caching
// ✅ Good: Redis caching
const redis = require('redis');
const client = redis.createClient();
async function getUser(id) {
const cached = await client.get(`user:${id}`);
if (cached) return JSON.parse(cached);
const user = await User.findById(id);
await client.setex(`user:${id}`, 3600, JSON.stringify(user));
return user;
}
// ✅ Good: Cache invalidation
async function updateUser(id, updates) {
const user = await User.findByIdAndUpdate(id, updates);
await client.del(`user:${id}`);
return user;
}
CDN Caching
// ✅ Good: CDN configuration
// Serve static assets from CDN
<script src="https://cdn.example.com/app.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/style.css" />
// ✅ Good: Cache headers for CDN
app.get('/static/*', (req, res) => {
res.set('Cache-Control', 'public, max-age=31536000, immutable');
res.sendFile(req.path);
});
Cache Strategies
Cache-Aside
// ✅ Good: Cache-aside pattern
async function getUser(id) {
// Check cache
const cached = await cache.get(`user:${id}`);
if (cached) return cached;
// Fetch from database
const user = await User.findById(id);
// Store in cache
await cache.set(`user:${id}`, user, 3600);
return user;
}
Write-Through
// ✅ Good: Write-through pattern
async function updateUser(id, updates) {
// Update database
const user = await User.findByIdAndUpdate(id, updates);
// Update cache
await cache.set(`user:${id}`, user);
return user;
}
Write-Behind
// ✅ Good: Write-behind pattern
async function updateUser(id, updates) {
// Update cache immediately
await cache.set(`user:${id}`, updates);
// Update database asynchronously
setTimeout(async () => {
await User.findByIdAndUpdate(id, updates);
}, 1000);
}
Best Practices
- Set appropriate TTL:
// ✅ Good: Appropriate TTL await cache.setex('user:1', 3600, user); // 1 hour await cache.setex('config', 86400, config); // 1 day // ❌ Bad: No TTL await cache.set('user:1', user); ```javascript - Invalidate cache:
// ✅ Good: Invalidate on update async function updateUser(id, updates) { await User.findByIdAndUpdate(id, updates); await cache.del(`user:${id}`); } // ❌ Bad: No invalidation async function updateUser(id, updates) { await User.findByIdAndUpdate(id, updates); } ```javascript - Use cache headers:
// ✅ Good: Cache headers res.set('Cache-Control', 'public, max-age=3600'); // ❌ Bad: No cache headers res.json(data);
Summary
Caching is essential. Key takeaways:
- Use browser caching
- Implement server caching
- Use CDN
- Set appropriate TTL
- Invalidate cache
- Use cache headers
- Monitor cache hit rate
- Improve performance
Related Resources
Next Steps
- Learn about Monitoring
- Explore DevOps
- Study Infrastructure
- Practice caching
- Improve performance
Comments