11 KiB
11 KiB
Phase 4 - Configuration & Tuning Guide
Overview
Phase 4 provides multiple configuration options to optimize for different use cases and environments.
Service Configurations
1. ClientCacheService
Memory Cache
Default: 50 items, 30-minute TTL
// In client-cache.service.ts
private readonly maxMemoryItems = 50;
// Usage
cache.setMemory(key, value, 30 * 60 * 1000); // 30 minutes
Tuning:
// For low-memory devices
private readonly maxMemoryItems = 25;
// For high-memory devices
private readonly maxMemoryItems = 100;
// For high-traffic scenarios
private readonly maxMemoryItems = 150;
Persistent Cache
Default: 200 items, LRU eviction
// In client-cache.service.ts
private readonly maxPersistentItems = 200;
Tuning:
// For mobile
private readonly maxPersistentItems = 50;
// For desktop
private readonly maxPersistentItems = 500;
// For high-traffic
private readonly maxPersistentItems = 1000;
TTL Configuration
Choose appropriate TTLs based on update frequency:
// Frequently updated content (5 minutes)
cache.setMemory(`note_${id}`, content, 5 * 60 * 1000);
// Standard content (30 minutes)
cache.setMemory(`note_${id}`, content, 30 * 60 * 1000);
// Rarely updated content (1 hour)
cache.setMemory(`note_${id}`, content, 60 * 60 * 1000);
// Very stable content (2 hours)
cache.setMemory(`note_${id}`, content, 2 * 60 * 60 * 1000);
2. NotePreloaderService
Preload Distance
How many notes to preload on each side of current note:
// In note-preloader.service.ts
private preloadConfig = {
preloadDistance: 2, // Default: 2 notes each side
};
// Runtime configuration
preloader.setConfig({ preloadDistance: 1 }); // Conservative
preloader.setConfig({ preloadDistance: 2 }); // Balanced
preloader.setConfig({ preloadDistance: 3 }); // Aggressive
preloader.setConfig({ preloadDistance: 5 }); // Very aggressive
Recommendations:
| Scenario | Distance | Rationale |
|---|---|---|
| Mobile / Low bandwidth | 1 | Minimize network usage |
| Standard desktop | 2 | Good balance |
| High-speed network | 3-4 | Maximize prefetch |
| Very fast network | 5+ | Aggressive prefetch |
Concurrent Loads
Max simultaneous preload operations:
private preloadConfig = {
maxConcurrentLoads: 3, // Default
};
// Runtime configuration
preloader.setConfig({ maxConcurrentLoads: 1 }); // Sequential
preloader.setConfig({ maxConcurrentLoads: 2 }); // Conservative
preloader.setConfig({ maxConcurrentLoads: 3 }); // Balanced
preloader.setConfig({ maxConcurrentLoads: 5 }); // Aggressive
Recommendations:
| Scenario | Concurrent | Rationale |
|---|---|---|
| Mobile / Limited bandwidth | 1-2 | Prevent congestion |
| Standard connection | 3 | Good parallelism |
| Fast connection | 4-5 | Maximum parallelism |
| Server-side limited | 2-3 | Respect server |
Enable/Disable
// Disable preloading if needed
preloader.setConfig({ enabled: false });
// Re-enable
preloader.setConfig({ enabled: true });
3. PerformanceProfilerService
Sample Size
Max samples per operation (default: 100):
// In performance-profiler.service.ts
private readonly maxSamples = 100;
Tuning:
// For quick feedback (less memory)
private readonly maxSamples = 50;
// Standard (balanced)
private readonly maxSamples = 100;
// For detailed analysis
private readonly maxSamples = 200;
Environment-Specific Configuration
Development Environment
// Enable all features for debugging
preloader.setConfig({
enabled: true,
maxConcurrentLoads: 3,
preloadDistance: 2
});
// Keep detailed metrics
profiler.maxSamples = 100;
// Show performance panel
// (automatically enabled on localhost)
Production Environment
// Conservative settings for stability
preloader.setConfig({
enabled: true,
maxConcurrentLoads: 2,
preloadDistance: 1
});
// Reduce memory usage
cache.maxMemoryItems = 30;
cache.maxPersistentItems = 100;
// Reduce metrics overhead
profiler.maxSamples = 50;
// Hide performance panel
// (automatically hidden in production)
Mobile Environment
// Minimal preloading for bandwidth
preloader.setConfig({
enabled: true,
maxConcurrentLoads: 1,
preloadDistance: 1
});
// Reduce memory footprint
cache.maxMemoryItems = 20;
cache.maxPersistentItems = 50;
// Shorter TTL for mobile
cache.setMemory(key, value, 5 * 60 * 1000); // 5 minutes
High-Traffic Environment
// Aggressive preloading
preloader.setConfig({
enabled: true,
maxConcurrentLoads: 5,
preloadDistance: 3
});
// Large caches
cache.maxMemoryItems = 100;
cache.maxPersistentItems = 500;
// Longer TTL
cache.setMemory(key, value, 60 * 60 * 1000); // 1 hour
Dynamic Configuration
Network-Aware Configuration
// Detect network speed and adjust
if (navigator.connection?.effectiveType === '4g') {
preloader.setConfig({ preloadDistance: 3, maxConcurrentLoads: 5 });
} else if (navigator.connection?.effectiveType === '3g') {
preloader.setConfig({ preloadDistance: 2, maxConcurrentLoads: 3 });
} else {
preloader.setConfig({ preloadDistance: 1, maxConcurrentLoads: 1 });
}
Device-Aware Configuration
// Detect device type
const isLowEndDevice = navigator.deviceMemory < 4;
const isHighEndDevice = navigator.deviceMemory >= 8;
if (isLowEndDevice) {
cache.maxMemoryItems = 20;
preloader.setConfig({ preloadDistance: 1 });
} else if (isHighEndDevice) {
cache.maxMemoryItems = 100;
preloader.setConfig({ preloadDistance: 3 });
}
Battery-Aware Configuration
// Reduce activity on low battery
if (navigator.getBattery) {
navigator.getBattery().then(battery => {
if (battery.level < 0.2) {
preloader.setConfig({ enabled: false });
}
});
}
Performance Tuning
Identifying Bottlenecks
// Get bottleneck analysis
const bottlenecks = profiler.analyzeBottlenecks();
console.log('Slow operations:', bottlenecks.slowOperations);
console.log('Frequent operations:', bottlenecks.frequentOperations);
// Adjust configuration based on findings
if (bottlenecks.slowOperations.length > 0) {
// Reduce concurrent loads
preloader.setConfig({ maxConcurrentLoads: 2 });
}
Optimizing Cache Hit Rate
// Monitor cache statistics
const stats = cache.getStats();
const hitRate = stats.memory.size / stats.memory.maxSize;
if (hitRate < 0.5) {
// Increase cache size
cache.maxMemoryItems = 100;
} else if (hitRate > 0.9) {
// Cache is efficient, can reduce size
cache.maxMemoryItems = 50;
}
Reducing Memory Usage
// Monitor memory
const metrics = profiler.exportMetrics();
const memoryUsage = metrics.memory?.used;
if (memoryUsage > 100 * 1024 * 1024) {
// Reduce cache sizes
cache.maxMemoryItems = 30;
cache.maxPersistentItems = 100;
// Reduce preload distance
preloader.setConfig({ preloadDistance: 1 });
}
Configuration Profiles
Profile: Conservative (Mobile/Low-End)
// Minimal resource usage
const conservativeProfile = {
cache: {
maxMemoryItems: 20,
maxPersistentItems: 50,
ttl: 5 * 60 * 1000 // 5 minutes
},
preloader: {
enabled: true,
maxConcurrentLoads: 1,
preloadDistance: 1
},
profiler: {
maxSamples: 50
}
};
Profile: Balanced (Standard Desktop)
// Good balance of performance and resources
const balancedProfile = {
cache: {
maxMemoryItems: 50,
maxPersistentItems: 200,
ttl: 30 * 60 * 1000 // 30 minutes
},
preloader: {
enabled: true,
maxConcurrentLoads: 3,
preloadDistance: 2
},
profiler: {
maxSamples: 100
}
};
Profile: Aggressive (High-End/Fast Network)
// Maximum performance
const aggressiveProfile = {
cache: {
maxMemoryItems: 100,
maxPersistentItems: 500,
ttl: 60 * 60 * 1000 // 1 hour
},
preloader: {
enabled: true,
maxConcurrentLoads: 5,
preloadDistance: 3
},
profiler: {
maxSamples: 200
}
};
Applying Profiles
// Apply profile at startup
function applyProfile(profile: any) {
cache.maxMemoryItems = profile.cache.maxMemoryItems;
cache.maxPersistentItems = profile.cache.maxPersistentItems;
preloader.setConfig({
maxConcurrentLoads: profile.preloader.maxConcurrentLoads,
preloadDistance: profile.preloader.preloadDistance,
enabled: profile.preloader.enabled
});
profiler.maxSamples = profile.profiler.maxSamples;
}
// Detect environment and apply
if (isProduction()) {
applyProfile(conservativeProfile);
} else if (isHighEndDevice()) {
applyProfile(aggressiveProfile);
} else {
applyProfile(balancedProfile);
}
Monitoring Configuration Impact
Before and After Metrics
// Capture baseline
const baselineMetrics = profiler.exportMetrics();
// Apply new configuration
preloader.setConfig({ preloadDistance: 3 });
// Wait for warm-up period
setTimeout(() => {
// Capture new metrics
const newMetrics = profiler.exportMetrics();
// Compare
console.log('Baseline:', baselineMetrics);
console.log('After change:', newMetrics);
}, 5 * 60 * 1000); // 5 minutes
Configuration Best Practices
- Start Conservative: Begin with minimal settings, increase gradually
- Monitor Impact: Always measure before and after changes
- Test on Real Devices: Configuration should match target devices
- Document Changes: Keep track of why configurations were changed
- Periodic Review: Re-evaluate configuration as usage patterns change
- A/B Testing: Test different configurations with user segments
Troubleshooting Configuration
High Memory Usage
// Reduce cache sizes
cache.maxMemoryItems = 30;
cache.maxPersistentItems = 100;
// Reduce preload distance
preloader.setConfig({ preloadDistance: 1 });
// Increase cleanup frequency
setInterval(() => cache.cleanup(), 2 * 60 * 1000); // Every 2 minutes
Low Cache Hit Rate
// Increase cache sizes
cache.maxMemoryItems = 100;
cache.maxPersistentItems = 500;
// Increase TTL
cache.setMemory(key, value, 60 * 60 * 1000); // 1 hour
// Increase preload distance
preloader.setConfig({ preloadDistance: 3 });
Slow Navigation
// Increase preload distance
preloader.setConfig({ preloadDistance: 3 });
// Increase concurrent loads
preloader.setConfig({ maxConcurrentLoads: 5 });
// Increase cache sizes
cache.maxMemoryItems = 100;
Configuration Guide: Complete Profiles: 3 (Conservative, Balanced, Aggressive) Dynamic Configuration: Network, Device, Battery aware