veza/config/incus/LIGHTHOUSE_AUDIT_REPORT.md
senke f0ba7de543 state-ownership: delete unused optimisticStoreUpdates.ts file
- Deleted apps/web/src/utils/optimisticStoreUpdates.ts (unused file)
- File was unused - no imports found in codebase
- Mutations already use React Query's onMutate pattern
- No TypeScript errors after deletion
- Actions 4.4.1.2 and 4.4.1.3 complete
2026-01-15 19:26:53 +01:00

347 lines
9.8 KiB
Markdown

# LIGHTHOUSE AUDIT REPORT - Veza Platform
**Date:** 2026-01-15
**URL:** https://10.10.10.6/
**Lighthouse Version:** 13.0.1
---
## 📊 RÉSUMÉ EXÉCUTIF
### Scores Globaux
- **Performance:** ❌ Non calculé (erreur NO_LCP)
- **Accessibility:** ✅ **93/100** (Bien)
- **Best Practices:** ✅ **96/100** (Excellent)
- **SEO:** ✅ **91/100** (Bien)
### Métriques de Performance Observées
- **First Contentful Paint (FCP):** 0.7s ✅ (Excellent)
- **Speed Index:** 0.7s ✅ (Excellent)
- **Cumulative Layout Shift (CLS):** 0 ✅ (Parfait)
- **Max Potential FID:** 20ms ✅ (Excellent)
- **Total Byte Weight:** 560 KiB (Acceptable)
---
## 🔴 PROBLÈMES CRITIQUES
### 1. Erreur JavaScript Console
**Sévérité:** 🔴 Critique
**Impact:** Application peut ne pas fonctionner correctement
```
TypeError: Cannot set properties of undefined (setting 'Children')
at chunk-C3tlqKw3.js:2:4843
```
**Cause:** Problème d'initialisation React - React.Children non disponible au moment de l'accès.
**Solution:** ✅ Déjà en cours de correction dans `apps/web/src/main.tsx` avec l'initialisation globale de React.
**Action requise:** Vérifier que le fix est bien déployé en production.
---
### 2. robots.txt Invalide
**Sévérité:** 🟡 Moyen
**Impact:** SEO - 59 erreurs de syntaxe
**Problème:** Le fichier `/robots.txt` retourne du HTML au lieu d'un fichier robots.txt valide.
**Solution:** Créer un fichier `robots.txt` valide dans `apps/web/public/robots.txt`.
**Action requise:** Créer le fichier robots.txt (voir section Solutions).
---
### 3. Missing Main Landmark
**Sévérité:** 🟡 Moyen
**Impact:** Accessibilité - Navigation difficile pour les lecteurs d'écran
**Problème:** Le document HTML ne contient pas d'élément `<main>` pour identifier le contenu principal.
**Solution:** Ajouter un élément `<main>` dans le Layout ou App component.
**Action requise:** Modifier le composant Layout pour inclure `<main>`.
---
## 🟡 PROBLÈMES MOYENS
### 4. Headers de Sécurité Manquants
**Sévérité:** 🟡 Moyen
**Impact:** Sécurité
**Headers manquants:**
-**Content-Security-Policy (CSP):** Aucun CSP en mode enforcement
-**Strict-Transport-Security (HSTS):** Aucun header HSTS trouvé
-**Cross-Origin-Opener-Policy (COOP):** Aucun header COOP trouvé
-**Trusted Types:** Pas de directive require-trusted-types-for dans CSP
**Solution:** Ajouter les headers dans la configuration Apache/Nginx.
**Action requise:** Mettre à jour `config/incus/apache/veza-web.conf` (voir section Solutions).
---
### 5. Source Maps Manquantes ou Invalides
**Sévérité:** 🟡 Moyen
**Impact:** Débogage en production
**Problème:**
- Plusieurs fichiers JS retournent du HTML au lieu de source maps
- SyntaxError: "Unexpected token '<', \"<!doctype \"... is not valid JSON"
**Fichiers affectés:**
- `chunk-C3tlqKw3.js.map`
- `index-sZ6H8osd.js.map`
- `chunk-VMUEamc6.js.map`
- Et 6 autres fichiers
**Solution:**
1. Vérifier que Vite génère bien les source maps en production
2. Configurer Apache pour servir les `.map` files avec le bon Content-Type
3. Ou désactiver les source maps en production (recommandé pour la sécurité)
**Action requise:** Vérifier la configuration Vite et Apache.
---
### 6. Back/Forward Cache (bfcache) Désactivé
**Sévérité:** 🟢 Faible
**Impact:** Performance de navigation
**Raisons:**
1. Back/forward cache désactivé par flags
2. `cache-control:no-store` sur la ressource principale
3. Requêtes JavaScript avec `Cache-Control: no-store`
4. Désactivé par ligne de commande
**Solution:** Ajuster les headers Cache-Control pour permettre le bfcache.
**Action requise:** Modifier les headers Cache-Control (voir section Solutions).
---
## ✅ POINTS POSITIFS
### Performance
- ✅ FCP excellent (0.7s)
- ✅ Speed Index excellent (0.7s)
- ✅ CLS parfait (0)
- ✅ Pas de long tasks bloquantes
- ✅ Temps de réponse serveur excellent (1ms)
- ✅ HTTP/2 utilisé
### Accessibilité
- ✅ Document title présent
- ✅ Langue HTML définie (lang="en")
- ✅ Viewport configuré correctement
- ✅ Pas d'erreurs ARIA majeures
- ✅ Pas de problèmes de contraste détectés
### SEO
- ✅ Meta description présente
- ✅ Status HTTP 200
- ✅ Liens crawlables
- ✅ Page indexable
- ✅ Hreflang valide
### Best Practices
- ✅ HTTPS utilisé
- ✅ Pas de cookies tiers
- ✅ Pas d'APIs dépréciées
- ✅ Pas de requêtes de géolocalisation au chargement
- ✅ Pas de requêtes de notifications au chargement
---
## 🔧 SOLUTIONS DÉTAILLÉES
### Solution 1: Créer robots.txt
Créer le fichier `apps/web/public/robots.txt`:
```txt
User-agent: *
Allow: /
# Sitemap (à ajouter quand disponible)
# Sitemap: https://10.10.10.6/sitemap.xml
```
**Action:** Créer le fichier et redéployer.
---
### Solution 2: Ajouter Main Landmark
Modifier `apps/web/src/components/layout/DashboardLayout.tsx` ou créer un wrapper:
```tsx
// Dans DashboardLayout ou App.tsx
<main id="main-content" role="main">
{children}
</main>
```
**Action:** Ajouter l'élément `<main>` dans le Layout.
---
### Solution 3: Ajouter Headers de Sécurité
Mettre à jour `config/incus/apache/veza-web.conf`:
```apache
# Security headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# HSTS (Strict-Transport-Security)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# COOP (Cross-Origin-Opener-Policy)
Header always set Cross-Origin-Opener-Policy "same-origin"
# CSP (Content Security Policy) - À adapter selon les besoins
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://fonts.googleapis.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' ws: wss:; frame-ancestors 'self';"
```
**Action:** Ajouter ces headers dans la configuration Apache.
---
### Solution 4: Corriger Source Maps
**Option A: Désactiver source maps en production (Recommandé)**
Dans `apps/web/vite.config.ts`:
```typescript
build: {
sourcemap: process.env.NODE_ENV === 'development',
// ...
}
```
**Option B: Configurer Apache pour servir les source maps**
Dans `config/incus/apache/veza-web.conf`:
```apache
# Source maps
<LocationMatch "^/js/.*\.map$">
Header set Content-Type "application/json"
Header set Cache-Control "no-cache, no-store, must-revalidate"
</LocationMatch>
```
**Action:** Choisir une option et l'implémenter.
---
### Solution 5: Ajuster Cache-Control pour bfcache
Modifier les headers Cache-Control pour permettre le bfcache:
```apache
# Permettre bfcache pour index.html (mais toujours no-cache pour le contenu)
<LocationMatch "^/index\.html$">
Header set Cache-Control "no-cache, must-revalidate"
# Retirer no-store pour permettre bfcache
</LocationMatch>
```
**Action:** Ajuster les headers Cache-Control.
---
## 📋 CHECKLIST D'ACTIONS
### Priorité Haute (Critique)
- [ ] Vérifier que le fix React.Children est déployé
- [ ] Créer le fichier robots.txt
- [ ] Ajouter l'élément `<main>` dans le Layout
### Priorité Moyenne
- [ ] Ajouter les headers de sécurité (CSP, HSTS, COOP)
- [ ] Corriger ou désactiver les source maps
- [ ] Ajuster les headers Cache-Control pour bfcache
### Priorité Basse (Amélioration)
- [ ] Optimiser les fonts (font-display: swap déjà présent)
- [ ] Réduire la taille des bundles JavaScript (560 KiB acceptable)
- [ ] Ajouter un sitemap.xml
---
## 📈 MÉTRIQUES DÉTAILLÉES
### Network Requests
- **Total Requests:** 14
- **Total Transfer Size:** 560 KiB
- **Scripts:** 9 fichiers (338 KiB)
- **Stylesheets:** 2 fichiers (184 KiB)
- **Fonts:** 1 fichier (49 KiB)
### Performance Breakdown
- **Main Thread Work:** 103.8ms (Excellent)
- Other: 77ms
- Style & Layout: 13.2ms
- Parse HTML & CSS: 6.6ms
- Script Evaluation: 4.9ms
- **JavaScript Execution:** 3.7ms (Excellent)
- **Network RTT:** 0.04ms (local), 9ms (Google Fonts)
### Third-Party Resources
- **Google Fonts:** 203 KiB
- CSS: 154 KiB
- Font file: 49 KiB
---
## 🔍 OBSERVATIONS
### Points à Surveiller
1. **LCP Error (NO_LCP):** Lighthouse n'a pas pu calculer le Largest Contentful Paint. Cela peut indiquer que la page ne charge pas complètement ou qu'il n'y a pas d'élément LCP identifiable.
2. **DOM Size:** Très petit (3 éléments seulement), ce qui suggère que React ne s'est peut-être pas complètement rendu lors de l'audit.
3. **Console Error:** L'erreur React.Children suggère un problème de timing dans le chargement des modules.
### Recommandations Générales
1. **Monitoring:** Mettre en place un monitoring continu avec Lighthouse CI
2. **Testing:** Ajouter des tests E2E pour vérifier le rendu complet de l'application
3. **Performance Budget:** Définir un budget de performance (ex: < 600 KiB total)
4. **Security Audit:** Effectuer un audit de sécurité complet
---
## 📝 NOTES TECHNIQUES
### Configuration Actuelle
- **Protocol:** HTTP/2
- **Compression:** Gzip activé
- **Cache:** Configuré pour les assets statiques
- **SPA Routing:** Configuré correctement
### Environnement
- **URL:** https://10.10.10.6/
- **User Agent:** Chrome 143.0.0.0 (Linux)
- **Form Factor:** Desktop (mobile emulation désactivée)
- **Throttling:** Simulé (RTT: 40ms, Throughput: 10Mbps)
---
## 🎯 OBJECTIFS DE PROCHAINES ITÉRATIONS
1. **Performance Score:** Atteindre 90+ (actuellement non calculé)
2. **Accessibility Score:** Maintenir 95+ (actuellement 93)
3. **Best Practices Score:** Maintenir 95+ (actuellement 96)
4. **SEO Score:** Atteindre 95+ (actuellement 91)
---
**Prochain Audit:** À planifier après correction des problèmes critiques