Backend Go: - Remplacement complet des anciennes migrations par la base V1 alignée sur ORIGIN. - Durcissement global du parsing JSON (BindAndValidateJSON + RespondWithAppError). - Sécurisation de config.go, CORS, statuts de santé et monitoring. - Implémentation des transactions P0 (RBAC, duplication de playlists, social toggles). - Ajout d’un job worker structuré (emails, analytics, thumbnails) + tests associés. - Nouvelle doc backend : AUDIT_CONFIG, BACKEND_CONFIG, AUTH_PASSWORD_RESET, JOB_WORKER_*. Chat server (Rust): - Refonte du pipeline JWT + sécurité, audit et rate limiting avancé. - Implémentation complète du cycle de message (read receipts, delivered, edit/delete, typing). - Nettoyage des panics, gestion d’erreurs robuste, logs structurés. - Migrations chat alignées sur le schéma UUID et nouvelles features. Stream server (Rust): - Refonte du moteur de streaming (encoding pipeline + HLS) et des modules core. - Transactions P0 pour les jobs et segments, garanties d’atomicité. - Documentation détaillée de la pipeline (AUDIT_STREAM_*, DESIGN_STREAM_PIPELINE, TRANSACTIONS_P0_IMPLEMENTATION). Documentation & audits: - TRIAGE.md et AUDIT_STABILITY.md à jour avec l’état réel des 3 services. - Cartographie complète des migrations et des transactions (DB_MIGRATIONS_*, DB_TRANSACTION_PLAN, AUDIT_DB_TRANSACTIONS, TRANSACTION_TESTS_PHASE3). - Scripts de reset et de cleanup pour la lab DB et la V1. Ce commit fige l’ensemble du travail de stabilisation P0 (UUID, backend, chat et stream) avant les phases suivantes (Coherence Guardian, WS hardening, etc.).
853 lines
22 KiB
Markdown
853 lines
22 KiB
Markdown
# ORIGIN_PERFORMANCE_TARGETS.md
|
|
|
|
## 📋 RÉSUMÉ EXÉCUTIF
|
|
|
|
Ce document définit les objectifs de performance mesurables et définitifs pour tous les composants de la plateforme Veza. Il spécifie targets précis pour latence (< 100ms p95), throughput (10K req/s), database (< 10ms queries), frontend (Lighthouse 100), avec monitoring (Prometheus), alerting (PagerDuty), et optimization strategies garantissant expérience utilisateur fluide et scalabilité production.
|
|
|
|
## 🎯 OBJECTIFS
|
|
|
|
### Objectif Principal
|
|
Garantir performance optimale avec latence API < 100ms (p95), temps chargement < 2s, zero buffering audio/vidéo, et scalabilité jusqu'à 100K utilisateurs concurrents avec dégradation gracieuse.
|
|
|
|
### Objectifs Secondaires
|
|
- Optimiser ressources (CPU < 70%, RAM < 80%)
|
|
- Réduire coûts infrastructure (efficient resource utilization)
|
|
- Détecter régressions performance automatiquement (CI/CD)
|
|
- Fournir expérience utilisateur fluide (no jank, 60 FPS)
|
|
|
|
## 📖 TABLE DES MATIÈRES
|
|
|
|
1. [Performance Philosophy](#1-performance-philosophy)
|
|
2. [Backend Performance Targets](#2-backend-performance-targets)
|
|
3. [Frontend Performance Targets](#3-frontend-performance-targets)
|
|
4. [Database Performance Targets](#4-database-performance-targets)
|
|
5. [Network Performance Targets](#5-network-performance-targets)
|
|
6. [Audio Streaming Performance](#6-audio-streaming-performance)
|
|
7. [Monitoring & Alerting](#7-monitoring--alerting)
|
|
8. [Performance Testing](#8-performance-testing)
|
|
9. [Optimization Strategies](#9-optimization-strategies)
|
|
10. [Performance Budgets](#10-performance-budgets)
|
|
|
|
## 🔒 RÈGLES IMMUABLES
|
|
|
|
1. **API Latency**: p95 < 100ms, p99 < 200ms - CI/CD bloque si dépassé
|
|
2. **Database Queries**: p95 < 10ms - N+1 queries interdites
|
|
3. **Frontend Load**: First Contentful Paint < 1.5s, Time to Interactive < 3.5s
|
|
4. **Bundle Size**: Initial JS bundle < 200KB gzipped
|
|
5. **Memory Leaks**: Zero memory leaks tolérés (CI/CD checks)
|
|
6. **Audio Streaming**: Zero buffering, latency < 50ms
|
|
7. **Throughput**: Min 10K req/s sustained (backend)
|
|
8. **Resource Usage**: CPU < 70%, Memory < 80% (average)
|
|
9. **Cache Hit Rate**: > 90% for frequently accessed data
|
|
10. **Mobile Performance**: Lighthouse Performance score ≥ 90
|
|
|
|
## 1. PERFORMANCE PHILOSOPHY
|
|
|
|
### 1.1 Performance Principles
|
|
|
|
**User-Centric Performance**:
|
|
- **Perceived Performance > Actual Performance**: Users care about what they experience
|
|
- **Critical Rendering Path**: Optimize what users see first
|
|
- **Progressive Enhancement**: Core functionality works fast, enhancements load progressively
|
|
|
|
**Performance Metrics Hierarchy**:
|
|
```
|
|
1. Core Web Vitals (Google)
|
|
- LCP (Largest Contentful Paint) < 2.5s
|
|
- FID (First Input Delay) < 100ms
|
|
- CLS (Cumulative Layout Shift) < 0.1
|
|
|
|
2. Custom Business Metrics
|
|
- Time to First Track Play < 3s
|
|
- Search Results < 500ms
|
|
- Upload Progress Feedback < 100ms
|
|
```
|
|
|
|
### 1.2 Performance SLOs (Service Level Objectives)
|
|
|
|
| Metric | Target | Stretch Goal |
|
|
|--------|--------|--------------|
|
|
| **API Response Time (p95)** | < 100ms | < 50ms |
|
|
| **API Response Time (p99)** | < 200ms | < 100ms |
|
|
| **Database Query (p95)** | < 10ms | < 5ms |
|
|
| **Frontend Load (FCP)** | < 1.5s | < 1s |
|
|
| **Frontend Load (TTI)** | < 3.5s | < 2s |
|
|
| **Audio Stream Start** | < 500ms | < 300ms |
|
|
| **Search Results** | < 500ms | < 200ms |
|
|
| **Uptime** | 99.9% | 99.99% |
|
|
|
|
## 2. BACKEND PERFORMANCE TARGETS
|
|
|
|
### 2.1 API Response Times
|
|
|
|
**Endpoints Performance Targets**:
|
|
|
|
| Endpoint Category | p50 | p95 | p99 | Examples |
|
|
|-------------------|-----|-----|-----|----------|
|
|
| **Simple Reads** | < 20ms | < 50ms | < 100ms | GET /users/{id}, GET /tracks/{id} |
|
|
| **Complex Reads** | < 50ms | < 100ms | < 200ms | GET /tracks (with filters), GET /search |
|
|
| **Writes** | < 50ms | < 150ms | < 300ms | POST /users, PUT /tracks/{id} |
|
|
| **File Uploads** | < 2s | < 5s | < 10s | POST /tracks (upload) |
|
|
| **Aggregations** | < 100ms | < 300ms | < 500ms | GET /analytics/dashboard |
|
|
|
|
**Critical Endpoints** (Strict Targets):
|
|
- `GET /tracks/{id}`: p95 < 30ms
|
|
- `POST /tracks/{id}/play`: p95 < 20ms
|
|
- `GET /search?q=`: p95 < 200ms
|
|
- `POST /auth/login`: p95 < 100ms
|
|
- `GET /feed`: p95 < 150ms
|
|
|
|
### 2.2 Throughput Targets
|
|
|
|
| Endpoint | Target RPS | Peak RPS | Concurrent Users |
|
|
|----------|------------|----------|------------------|
|
|
| **GET /tracks** | 5,000 | 10,000 | 50,000 |
|
|
| **POST /tracks/{id}/play** | 10,000 | 20,000 | 100,000 |
|
|
| **GET /search** | 2,000 | 5,000 | 20,000 |
|
|
| **POST /auth/login** | 500 | 1,000 | 5,000 |
|
|
| **WebSocket connections** | 10,000 | 20,000 | 20,000 |
|
|
|
|
### 2.3 Resource Utilization
|
|
|
|
**Per Service Limits**:
|
|
```yaml
|
|
backend-api:
|
|
cpu_usage: < 70% (average), < 90% (peak)
|
|
memory_usage: < 80% (average), < 95% (peak)
|
|
goroutines: < 10,000
|
|
database_connections: < 100 (per instance)
|
|
|
|
chat-server:
|
|
cpu_usage: < 60%
|
|
memory_usage: < 70%
|
|
websocket_connections: < 10,000 (per instance)
|
|
message_throughput: > 50,000 msg/s
|
|
|
|
stream-server:
|
|
cpu_usage: < 80% (audio processing intensive)
|
|
memory_usage: < 75%
|
|
concurrent_streams: > 5,000
|
|
bandwidth: > 10 Gbps
|
|
```
|
|
|
|
### 2.4 Error Rates
|
|
|
|
| Error Type | Target | Alert Threshold |
|
|
|------------|--------|-----------------|
|
|
| **4xx Errors** | < 1% | > 2% |
|
|
| **5xx Errors** | < 0.1% | > 0.5% |
|
|
| **Timeouts** | < 0.01% | > 0.1% |
|
|
| **Database Errors** | < 0.01% | > 0.05% |
|
|
|
|
## 3. FRONTEND PERFORMANCE TARGETS
|
|
|
|
### 3.1 Core Web Vitals
|
|
|
|
**Lighthouse Scores** (Target: 100):
|
|
- **Performance**: ≥ 95
|
|
- **Accessibility**: ≥ 100
|
|
- **Best Practices**: ≥ 100
|
|
- **SEO**: ≥ 100
|
|
|
|
**Detailed Metrics**:
|
|
|
|
| Metric | Good | Needs Improvement | Poor | Target |
|
|
|--------|------|-------------------|------|--------|
|
|
| **LCP (Largest Contentful Paint)** | ≤ 2.5s | 2.5s - 4.0s | > 4.0s | **< 2s** |
|
|
| **FID (First Input Delay)** | ≤ 100ms | 100ms - 300ms | > 300ms | **< 50ms** |
|
|
| **CLS (Cumulative Layout Shift)** | ≤ 0.1 | 0.1 - 0.25 | > 0.25 | **< 0.05** |
|
|
| **FCP (First Contentful Paint)** | ≤ 1.8s | 1.8s - 3.0s | > 3.0s | **< 1.5s** |
|
|
| **TTI (Time to Interactive)** | ≤ 3.8s | 3.8s - 7.3s | > 7.3s | **< 3.5s** |
|
|
| **TBT (Total Blocking Time)** | ≤ 200ms | 200ms - 600ms | > 600ms | **< 150ms** |
|
|
| **Speed Index** | ≤ 3.4s | 3.4s - 5.8s | > 5.8s | **< 3s** |
|
|
|
|
### 3.2 Bundle Size
|
|
|
|
**JavaScript Bundles**:
|
|
```
|
|
Initial Bundle (gzipped):
|
|
├── vendor.js (React, Router, etc.): < 150 KB
|
|
├── main.js (App code): < 50 KB
|
|
└── TOTAL: < 200 KB
|
|
|
|
Lazy-Loaded Bundles:
|
|
├── dashboard.js: < 30 KB
|
|
├── player.js: < 40 KB
|
|
├── upload.js: < 25 KB
|
|
└── admin.js: < 50 KB
|
|
|
|
CSS:
|
|
├── main.css (Tailwind): < 20 KB (purged)
|
|
└── fonts: < 50 KB (subset)
|
|
```
|
|
|
|
**Image Optimization**:
|
|
- **Hero Images**: < 100 KB (WebP)
|
|
- **Thumbnails**: < 20 KB (WebP)
|
|
- **Avatars**: < 10 KB (WebP)
|
|
- **Icons**: Inline SVG or sprite sheet < 5 KB
|
|
|
|
### 3.3 Runtime Performance
|
|
|
|
**Frame Rate**:
|
|
- **Animations**: 60 FPS (16.67ms per frame)
|
|
- **Scrolling**: Smooth (no jank)
|
|
- **Interactions**: < 100ms response time
|
|
|
|
**Memory Usage**:
|
|
- **Initial Load**: < 50 MB
|
|
- **Peak Usage**: < 150 MB
|
|
- **Memory Leaks**: Zero (CI/CD checks)
|
|
|
|
### 3.4 Mobile Performance
|
|
|
|
**Mobile-Specific Targets** (4G connection):
|
|
- **FCP**: < 2.5s
|
|
- **TTI**: < 5s
|
|
- **Bundle Size**: < 150 KB initial
|
|
- **Lighthouse Performance**: ≥ 90
|
|
|
|
## 4. DATABASE PERFORMANCE TARGETS
|
|
|
|
### 4.1 Query Performance
|
|
|
|
**Query Latency Targets**:
|
|
|
|
| Query Type | p50 | p95 | p99 | Examples |
|
|
|------------|-----|-----|-----|----------|
|
|
| **Simple SELECT** | < 2ms | < 5ms | < 10ms | SELECT * FROM users WHERE id = ? |
|
|
| **JOIN (2 tables)** | < 5ms | < 10ms | < 20ms | Users JOIN Tracks |
|
|
| **JOIN (3+ tables)** | < 10ms | < 20ms | < 50ms | Complex queries |
|
|
| **Aggregations** | < 10ms | < 30ms | < 100ms | COUNT, SUM, AVG |
|
|
| **Full-Text Search** | < 20ms | < 50ms | < 100ms | GIN index searches |
|
|
| **INSERT** | < 3ms | < 10ms | < 20ms | Single row insert |
|
|
| **UPDATE** | < 5ms | < 15ms | < 30ms | Single row update |
|
|
|
|
**Slow Query Threshold**: > 100ms (logged and investigated)
|
|
|
|
### 4.2 Connection Pool
|
|
|
|
**PgBouncer Configuration**:
|
|
```ini
|
|
[pgbouncer]
|
|
pool_mode = transaction
|
|
max_client_conn = 1000
|
|
default_pool_size = 25
|
|
min_pool_size = 10
|
|
reserve_pool_size = 5
|
|
max_db_connections = 100
|
|
|
|
# Performance
|
|
query_timeout = 30
|
|
idle_transaction_timeout = 60
|
|
```
|
|
|
|
**Metrics Targets**:
|
|
- **Connection Utilization**: < 80%
|
|
- **Wait Time**: < 10ms
|
|
- **Connection Errors**: < 0.01%
|
|
|
|
### 4.3 Index Performance
|
|
|
|
**Index Requirements**:
|
|
- **Index Hit Rate**: > 99%
|
|
- **Sequential Scans on Large Tables**: Zero (always use indexes)
|
|
- **Index Size**: < 20% of table size
|
|
|
|
**Monitoring Queries**:
|
|
```sql
|
|
-- Index usage
|
|
SELECT schemaname, tablename, indexname, idx_scan
|
|
FROM pg_stat_user_indexes
|
|
WHERE idx_scan < 100
|
|
ORDER BY idx_scan;
|
|
|
|
-- Missing indexes (high seq scans)
|
|
SELECT schemaname, tablename, seq_scan, seq_tup_read
|
|
FROM pg_stat_user_tables
|
|
WHERE seq_scan > 1000
|
|
ORDER BY seq_tup_read DESC;
|
|
```
|
|
|
|
### 4.4 Cache Hit Ratio
|
|
|
|
**PostgreSQL Cache**:
|
|
- **Shared Buffers Hit Rate**: > 95%
|
|
- **Index Hit Rate**: > 99%
|
|
|
|
**Application Cache (Redis)**:
|
|
- **Hit Rate**: > 90%
|
|
- **Latency**: < 1ms (p95)
|
|
- **Eviction Rate**: < 5%
|
|
|
|
## 5. NETWORK PERFORMANCE TARGETS
|
|
|
|
### 5.1 API Response Sizes
|
|
|
|
**Payload Sizes**:
|
|
```
|
|
Endpoints:
|
|
GET /users/{id}: < 2 KB
|
|
GET /tracks: < 50 KB (20 items)
|
|
GET /tracks/{id}: < 5 KB
|
|
GET /search: < 100 KB (50 results)
|
|
GET /feed: < 200 KB (100 items)
|
|
|
|
Images (served via CDN):
|
|
Thumbnail (200x200): < 20 KB (WebP)
|
|
Cover (800x800): < 100 KB (WebP)
|
|
Banner (1920x400): < 150 KB (WebP)
|
|
```
|
|
|
|
### 5.2 CDN Performance
|
|
|
|
**CDN Metrics**:
|
|
- **Cache Hit Ratio**: > 95%
|
|
- **Latency (p95)**: < 50ms
|
|
- **Bandwidth**: > 10 Gbps
|
|
- **Geographic Coverage**: < 100ms from any location
|
|
|
|
**CDN Configuration**:
|
|
```nginx
|
|
# Cache headers
|
|
location /static/ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
location /api/ {
|
|
expires -1;
|
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
}
|
|
```
|
|
|
|
### 5.3 Compression
|
|
|
|
**Gzip/Brotli Compression**:
|
|
- **Text (HTML, CSS, JS, JSON)**: Enabled (Brotli level 6)
|
|
- **Images**: Pre-compressed (WebP, AVIF)
|
|
- **Audio**: No compression (already compressed)
|
|
|
|
**Compression Ratios**:
|
|
- **JS/CSS**: 70-80% reduction
|
|
- **JSON**: 60-70% reduction
|
|
- **HTML**: 50-60% reduction
|
|
|
|
## 6. AUDIO STREAMING PERFORMANCE
|
|
|
|
### 6.1 Streaming Latency
|
|
|
|
**Latency Targets**:
|
|
- **Stream Start**: < 500ms (target: 300ms)
|
|
- **Buffer Fill**: < 200ms
|
|
- **Seek Time**: < 100ms
|
|
- **Quality Switch**: < 50ms (adaptive bitrate)
|
|
|
|
**Buffering**:
|
|
- **Initial Buffer**: 2 seconds
|
|
- **Rebuffering**: Zero (target)
|
|
- **Rebuffering Events**: < 0.1% of plays
|
|
|
|
### 6.2 Audio Quality
|
|
|
|
**Adaptive Bitrate Streaming**:
|
|
```
|
|
Network Speed → Bitrate:
|
|
< 500 kbps: 64 kbps (low quality)
|
|
500 kbps - 1 Mbps: 128 kbps (medium quality)
|
|
1 Mbps - 5 Mbps: 256 kbps (high quality)
|
|
> 5 Mbps: 320 kbps (premium quality)
|
|
```
|
|
|
|
**Format Support**:
|
|
- **Lossy**: MP3 (320 kbps), AAC (256 kbps), Opus (128 kbps)
|
|
- **Lossless**: FLAC (16-bit/44.1kHz)
|
|
|
|
### 6.3 Concurrent Streams
|
|
|
|
**Capacity Targets**:
|
|
- **Per Server**: 5,000 concurrent streams
|
|
- **Total Capacity**: 100,000 concurrent streams (20 servers)
|
|
- **Bandwidth**: 10 Gbps per server (avg 256 kbps/stream)
|
|
|
|
## 7. MONITORING & ALERTING
|
|
|
|
### 7.1 Prometheus Metrics
|
|
|
|
**RED Metrics** (Rate, Errors, Duration):
|
|
```promql
|
|
# Request Rate
|
|
rate(http_requests_total[5m])
|
|
|
|
# Error Rate
|
|
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
|
|
|
|
# Duration (Latency)
|
|
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
|
|
```
|
|
|
|
**USE Metrics** (Utilization, Saturation, Errors):
|
|
```promql
|
|
# CPU Utilization
|
|
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
|
|
|
|
# Memory Utilization
|
|
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
|
|
|
|
# Disk Saturation
|
|
rate(node_disk_io_time_seconds_total[5m])
|
|
```
|
|
|
|
### 7.2 Alerting Rules
|
|
|
|
**Critical Alerts** (PagerDuty):
|
|
```yaml
|
|
groups:
|
|
- name: critical_alerts
|
|
interval: 30s
|
|
rules:
|
|
- alert: HighErrorRate
|
|
expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.01
|
|
for: 2m
|
|
labels:
|
|
severity: critical
|
|
annotations:
|
|
summary: "High error rate detected ({{ $value }}%)"
|
|
|
|
- alert: HighLatency
|
|
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 0.1
|
|
for: 5m
|
|
labels:
|
|
severity: critical
|
|
annotations:
|
|
summary: "API latency p95 > 100ms ({{ $value }}s)"
|
|
|
|
- alert: DatabaseDown
|
|
expr: up{job="postgres"} == 0
|
|
for: 1m
|
|
labels:
|
|
severity: critical
|
|
annotations:
|
|
summary: "PostgreSQL is down"
|
|
```
|
|
|
|
**Warning Alerts** (Slack):
|
|
```yaml
|
|
- alert: ModerateCPUUsage
|
|
expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 70
|
|
for: 10m
|
|
labels:
|
|
severity: warning
|
|
annotations:
|
|
summary: "CPU usage > 70% for 10 minutes"
|
|
|
|
- alert: SlowQueries
|
|
expr: rate(postgres_slow_queries_total[5m]) > 10
|
|
for: 5m
|
|
labels:
|
|
severity: warning
|
|
annotations:
|
|
summary: "High number of slow queries (> 10/min)"
|
|
```
|
|
|
|
### 7.3 Grafana Dashboards
|
|
|
|
**Dashboard 1: API Performance**
|
|
- Request rate (RPS)
|
|
- Latency (p50, p95, p99)
|
|
- Error rate (4xx, 5xx)
|
|
- Throughput (MB/s)
|
|
- Active connections
|
|
|
|
**Dashboard 2: Database Performance**
|
|
- Query latency (p95, p99)
|
|
- Connection pool usage
|
|
- Cache hit ratio
|
|
- Slow queries (> 100ms)
|
|
- Replication lag
|
|
|
|
**Dashboard 3: Frontend Performance**
|
|
- Lighthouse scores (from CI/CD)
|
|
- Core Web Vitals (LCP, FID, CLS)
|
|
- Bundle sizes
|
|
- Resource loading times
|
|
- Error tracking (Sentry)
|
|
|
|
## 8. PERFORMANCE TESTING
|
|
|
|
### 8.1 Benchmarking
|
|
|
|
**Go Benchmarks**:
|
|
```go
|
|
func BenchmarkGetUserByID(b *testing.B) {
|
|
repo := setupRepo()
|
|
user := createTestUser(repo)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := repo.GetByID(user.ID)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Target: < 100,000 ns/op (0.1ms)
|
|
// BenchmarkGetUserByID-8 50000 25000 ns/op 1024 B/op 15 allocs/op
|
|
```
|
|
|
|
**Rust Benchmarks**:
|
|
```rust
|
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|
|
|
fn bench_get_user(c: &mut Criterion) {
|
|
let repo = setup_repo();
|
|
let user_id = create_test_user(&repo);
|
|
|
|
c.bench_function("get_user_by_id", |b| {
|
|
b.iter(|| {
|
|
repo.get_by_id(black_box(&user_id))
|
|
});
|
|
});
|
|
}
|
|
|
|
// Target: < 100μs
|
|
criterion_group!(benches, bench_get_user);
|
|
criterion_main!(benches);
|
|
```
|
|
|
|
### 8.2 Load Testing (k6)
|
|
|
|
**Continuous Load Test**:
|
|
```javascript
|
|
// k6-continuous.js
|
|
import http from 'k6/http';
|
|
import { check } from 'k6';
|
|
|
|
export const options = {
|
|
stages: [
|
|
{ duration: '5m', target: 1000 },
|
|
{ duration: '10m', target: 1000 },
|
|
{ duration: '5m', target: 0 },
|
|
],
|
|
thresholds: {
|
|
http_req_duration: ['p(95)<100', 'p(99)<200'],
|
|
http_req_failed: ['rate<0.01'],
|
|
},
|
|
};
|
|
|
|
export default function () {
|
|
const res = http.get('https://api.veza.app/v1/tracks');
|
|
check(res, {
|
|
'status is 200': (r) => r.status === 200,
|
|
'response time < 100ms': (r) => r.timings.duration < 100,
|
|
});
|
|
}
|
|
```
|
|
|
|
### 8.3 Performance Regression Detection
|
|
|
|
**CI/CD Integration**:
|
|
```yaml
|
|
# .github/workflows/performance.yml
|
|
name: Performance Tests
|
|
|
|
on: [push, pull_request]
|
|
|
|
jobs:
|
|
benchmark:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Run Go benchmarks
|
|
run: |
|
|
cd veza-backend-api
|
|
go test -bench=. -benchmem > bench-new.txt
|
|
|
|
- name: Compare with baseline
|
|
run: |
|
|
benchstat bench-baseline.txt bench-new.txt
|
|
# Fail if regression > 10%
|
|
|
|
- name: Update baseline (if main branch)
|
|
if: github.ref == 'refs/heads/main'
|
|
run: cp bench-new.txt bench-baseline.txt
|
|
```
|
|
|
|
## 9. OPTIMIZATION STRATEGIES
|
|
|
|
### 9.1 Backend Optimizations
|
|
|
|
**Database Query Optimization**:
|
|
```go
|
|
// ❌ BAD - N+1 query problem
|
|
func GetUsersWithTracks() ([]User, error) {
|
|
var users []User
|
|
db.Find(&users)
|
|
|
|
for i := range users {
|
|
db.Model(&users[i]).Association("Tracks").Find(&users[i].Tracks) // N queries
|
|
}
|
|
return users, nil
|
|
}
|
|
|
|
// ✅ GOOD - Single query with eager loading
|
|
func GetUsersWithTracks() ([]User, error) {
|
|
var users []User
|
|
err := db.Preload("Tracks").Find(&users).Error // 2 queries total
|
|
return users, err
|
|
}
|
|
```
|
|
|
|
**Caching Strategy**:
|
|
```go
|
|
// Cache frequently accessed data
|
|
func (s *TrackService) GetTrack(id string) (*Track, error) {
|
|
// Try cache first
|
|
cacheKey := fmt.Sprintf("track:%s", id)
|
|
if cached, err := s.cache.Get(cacheKey); err == nil {
|
|
var track Track
|
|
json.Unmarshal([]byte(cached), &track)
|
|
return &track, nil
|
|
}
|
|
|
|
// Cache miss - fetch from database
|
|
track, err := s.repo.GetByID(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Store in cache (1 hour TTL)
|
|
data, _ := json.Marshal(track)
|
|
s.cache.Set(cacheKey, string(data), 1*time.Hour)
|
|
|
|
return track, nil
|
|
}
|
|
```
|
|
|
|
### 9.2 Frontend Optimizations
|
|
|
|
**Code Splitting**:
|
|
```typescript
|
|
// Lazy load routes
|
|
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
|
const Upload = lazy(() => import('./pages/Upload'));
|
|
const Profile = lazy(() => import('./pages/Profile'));
|
|
|
|
function App() {
|
|
return (
|
|
<Suspense fallback={<LoadingSpinner />}>
|
|
<Routes>
|
|
<Route path="/dashboard" element={<Dashboard />} />
|
|
<Route path="/upload" element={<Upload />} />
|
|
<Route path="/profile/:id" element={<Profile />} />
|
|
</Routes>
|
|
</Suspense>
|
|
);
|
|
}
|
|
```
|
|
|
|
**Image Optimization**:
|
|
```typescript
|
|
// Use next-gen formats with fallback
|
|
<picture>
|
|
<source srcSet="/avatar.avif" type="image/avif" />
|
|
<source srcSet="/avatar.webp" type="image/webp" />
|
|
<img src="/avatar.jpg" alt="Avatar" loading="lazy" />
|
|
</picture>
|
|
|
|
// Or with responsive sizes
|
|
<img
|
|
src="/cover-800.webp"
|
|
srcSet="/cover-400.webp 400w, /cover-800.webp 800w, /cover-1600.webp 1600w"
|
|
sizes="(max-width: 640px) 400px, (max-width: 1024px) 800px, 1600px"
|
|
alt="Track cover"
|
|
loading="lazy"
|
|
/>
|
|
```
|
|
|
|
**Memoization**:
|
|
```typescript
|
|
// Memoize expensive calculations
|
|
const expensiveValue = useMemo(() => {
|
|
return tracks.filter(/* complex filter */).sort(/* expensive sort */);
|
|
}, [tracks]); // Only recalculate when tracks change
|
|
|
|
// Memoize components
|
|
const TrackItem = memo(({ track }: { track: Track }) => {
|
|
return <div>{track.title}</div>;
|
|
});
|
|
```
|
|
|
|
### 9.3 Database Optimizations
|
|
|
|
**Index Optimization**:
|
|
```sql
|
|
-- Add indexes for frequent queries
|
|
CREATE INDEX idx_tracks_user_genre ON tracks(user_id, genre) WHERE deleted_at IS NULL;
|
|
CREATE INDEX idx_tracks_published ON tracks(published_at DESC) WHERE is_public = true AND deleted_at IS NULL;
|
|
|
|
-- Partial index for active users
|
|
CREATE INDEX idx_users_active ON users(created_at DESC) WHERE is_active = true AND deleted_at IS NULL;
|
|
|
|
-- GIN index for full-text search
|
|
CREATE INDEX idx_tracks_search ON tracks USING GIN(to_tsvector('english', title || ' ' || artist)) WHERE deleted_at IS NULL;
|
|
```
|
|
|
|
**Query Optimization**:
|
|
```sql
|
|
-- Use EXPLAIN ANALYZE to identify slow queries
|
|
EXPLAIN ANALYZE
|
|
SELECT t.*, u.username
|
|
FROM tracks t
|
|
JOIN users u ON t.user_id = u.id
|
|
WHERE t.genre = 'electronic'
|
|
AND t.is_public = true
|
|
ORDER BY t.play_count DESC
|
|
LIMIT 20;
|
|
|
|
-- Optimize: Add covering index
|
|
CREATE INDEX idx_tracks_genre_plays ON tracks(genre, play_count DESC) INCLUDE (title, artist) WHERE is_public = true;
|
|
```
|
|
|
|
## 10. PERFORMANCE BUDGETS
|
|
|
|
### 10.1 Frontend Budgets
|
|
|
|
**JavaScript Budget**:
|
|
```json
|
|
{
|
|
"budget": [
|
|
{
|
|
"resourceSizes": [
|
|
{
|
|
"resourceType": "script",
|
|
"budget": 200
|
|
},
|
|
{
|
|
"resourceType": "stylesheet",
|
|
"budget": 20
|
|
},
|
|
{
|
|
"resourceType": "image",
|
|
"budget": 500
|
|
},
|
|
{
|
|
"resourceType": "font",
|
|
"budget": 50
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Lighthouse Budget (lighthouse-budget.json)**:
|
|
```json
|
|
{
|
|
"timings": [
|
|
{
|
|
"metric": "interactive",
|
|
"budget": 3500
|
|
},
|
|
{
|
|
"metric": "first-contentful-paint",
|
|
"budget": 1500
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### 10.2 Backend Budgets
|
|
|
|
**Per-Endpoint Budget**:
|
|
```yaml
|
|
endpoints:
|
|
GET /tracks:
|
|
latency_p95: 50ms
|
|
latency_p99: 100ms
|
|
database_queries: ≤ 2
|
|
cache_usage: required
|
|
|
|
POST /tracks/{id}/play:
|
|
latency_p95: 20ms
|
|
latency_p99: 50ms
|
|
database_queries: ≤ 1
|
|
cache_usage: optional
|
|
|
|
GET /search:
|
|
latency_p95: 200ms
|
|
latency_p99: 500ms
|
|
database_queries: ≤ 5
|
|
elasticsearch_usage: required
|
|
```
|
|
|
|
## ✅ CHECKLIST DE VALIDATION
|
|
|
|
### Performance Targets
|
|
- [ ] API latency p95 < 100ms for all critical endpoints
|
|
- [ ] Database queries p95 < 10ms
|
|
- [ ] Frontend Lighthouse Performance score ≥ 95
|
|
- [ ] Initial JS bundle < 200KB gzipped
|
|
- [ ] First Contentful Paint < 1.5s
|
|
- [ ] Time to Interactive < 3.5s
|
|
- [ ] Audio streaming start < 500ms
|
|
- [ ] Zero buffering during playback
|
|
|
|
### Monitoring
|
|
- [ ] Prometheus metrics configured
|
|
- [ ] Grafana dashboards created
|
|
- [ ] Alerting rules configured (critical + warning)
|
|
- [ ] Performance testing in CI/CD
|
|
- [ ] Regression detection automated
|
|
|
|
### Optimization
|
|
- [ ] Database indexes optimized
|
|
- [ ] N+1 queries eliminated
|
|
- [ ] Caching implemented (Redis)
|
|
- [ ] CDN configured
|
|
- [ ] Image optimization implemented
|
|
- [ ] Code splitting implemented
|
|
- [ ] Lazy loading implemented
|
|
|
|
## 📊 MÉTRIQUES DE SUCCÈS
|
|
|
|
### Performance Metrics
|
|
- **API Latency (p95)**: < 100ms
|
|
- **Frontend Load (FCP)**: < 1.5s
|
|
- **Lighthouse Performance**: ≥ 95
|
|
- **Uptime**: > 99.9%
|
|
|
|
### Resource Efficiency
|
|
- **CPU Usage**: < 70% (average)
|
|
- **Memory Usage**: < 80% (average)
|
|
- **Cache Hit Rate**: > 90%
|
|
- **Database Connection Utilization**: < 80%
|
|
|
|
### User Experience
|
|
- **Zero Buffering**: > 99.9% of plays
|
|
- **Error Rate**: < 0.1%
|
|
- **Time to First Play**: < 3s
|
|
|
|
## 🔄 HISTORIQUE DES VERSIONS
|
|
|
|
| Version | Date | Changements |
|
|
|---------|------|-------------|
|
|
| 1.0.0 | 2025-11-02 | Version initiale - Performance targets complets |
|
|
|
|
---
|
|
|
|
## ⚠️ AVERTISSEMENT
|
|
|
|
**CES TARGETS SONT IMMUABLES**
|
|
|
|
---
|
|
|
|
**Document créé par**: Performance Team + SRE
|
|
**Date de création**: 2025-11-02
|
|
**Prochaine révision**: Quarterly (2026-02-01)
|
|
**Propriétaire**: Performance Lead
|
|
|
|
**Statut**: ✅ **APPROUVÉ ET VERROUILLÉ**
|
|
|