505 lines
11 KiB
Markdown
505 lines
11 KiB
Markdown
# 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
|
|
|
|
```typescript
|
|
// In client-cache.service.ts
|
|
private readonly maxMemoryItems = 50;
|
|
|
|
// Usage
|
|
cache.setMemory(key, value, 30 * 60 * 1000); // 30 minutes
|
|
```
|
|
|
|
**Tuning**:
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// In client-cache.service.ts
|
|
private readonly maxPersistentItems = 200;
|
|
```
|
|
|
|
**Tuning**:
|
|
|
|
```typescript
|
|
// 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:
|
|
|
|
```typescript
|
|
// 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:
|
|
|
|
```typescript
|
|
// 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:
|
|
|
|
```typescript
|
|
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
|
|
|
|
```typescript
|
|
// Disable preloading if needed
|
|
preloader.setConfig({ enabled: false });
|
|
|
|
// Re-enable
|
|
preloader.setConfig({ enabled: true });
|
|
```
|
|
|
|
### 3. PerformanceProfilerService
|
|
|
|
#### Sample Size
|
|
|
|
Max samples per operation (default: 100):
|
|
|
|
```typescript
|
|
// In performance-profiler.service.ts
|
|
private readonly maxSamples = 100;
|
|
```
|
|
|
|
**Tuning**:
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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)
|
|
|
|
```typescript
|
|
// 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)
|
|
|
|
```typescript
|
|
// 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)
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
1. **Start Conservative**: Begin with minimal settings, increase gradually
|
|
2. **Monitor Impact**: Always measure before and after changes
|
|
3. **Test on Real Devices**: Configuration should match target devices
|
|
4. **Document Changes**: Keep track of why configurations were changed
|
|
5. **Periodic Review**: Re-evaluate configuration as usage patterns change
|
|
6. **A/B Testing**: Test different configurations with user segments
|
|
|
|
## Troubleshooting Configuration
|
|
|
|
### High Memory Usage
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|
|
|
|
```typescript
|
|
// 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
|