docs: add feature plan for preview images

- Architecture overview: previews/ directory structure
- Backend: Sharp library for image processing
- DB schema extension: preview_path column
- Frontend: Use previews in galleries, keep originals in slideshow
- Estimated effort: 12-22h (2-3 days)
- Expected improvement: ~95% size reduction, ~96% faster load times

Ref: feature/preview-images
This commit is contained in:
Matthias Lotz 2025-10-29 23:34:08 +01:00
parent 473465f363
commit 6ee736bcea

View File

@ -0,0 +1,312 @@
# Feature: Preview-Bilder für Galerie
**Branch:** `feature/preview-images`
**Datum:** 29. Oktober 2025
## 🎯 Ziel
Generierung und Verwendung von optimierten Preview-Bildern (Thumbnails) für Galerie-Ansichten, um:
- Ladezeiten drastisch zu reduzieren
- Bandbreite zu sparen
- User Experience zu verbessern
- Mobile Performance zu optimieren
---
## 📐 Architektur-Überblick
### Aktuelle Situation
- Bilder werden in voller Auflösung in Galerien geladen
- Path: `backend/src/data/images/` (Original-Bilder)
- Keine Thumbnails oder Preview-Varianten
### Ziel-Architektur
```
backend/src/data/
├── images/ # Original-Bilder (unverändert)
│ └── X_JeZj0TsQ.JPG
└── previews/ # NEU: Preview-Bilder (optimiert)
└── X_JeZj0TsQ.JPG (oder .webp)
```
### Thumbnail-Spezifikationen
- **Größe:** Max. 800px Breite (beibehält Aspect Ratio)
- **Format:** JPEG (85% Qualität) oder WebP (falls unterstützt)
- **Verwendung:** Galerie-Views (GroupsOverviewPage, ModerationGroupsPage)
- **Original:** Slideshow-View und Download behalten Original-Bilder
---
## 🔧 Technische Implementierung
### Backend: Sharp Library
**Warum Sharp?**
- Schnell (nutzt libvips)
- Unterstützt JPEG, PNG, WebP
- Läuft in Node.js ohne externe Binaries
- Unterstützt Resize, Optimize, Format-Konvertierung
**Installation:**
```bash
npm install sharp --save
```
### Datenbankschema-Erweiterung
```sql
-- Erweitere images Tabelle um preview_path
ALTER TABLE images ADD COLUMN preview_path TEXT;
-- Index für schnelle Abfragen
CREATE INDEX IF NOT EXISTS idx_images_preview_path ON images(preview_path);
```
---
## 📋 Implementierungs-Phasen
### Phase 1: Backend - Preview-Generierung (6-10h)
#### 1.1 Service-Layer erstellen
**Datei:** `backend/src/services/ImagePreviewService.js`
**Funktionen:**
- `generatePreview(originalPath, outputPath, options)` - Generiert einzelnes Preview
- `generatePreviewsForGroup(groupId)` - Batch-Generierung für Upload-Gruppe
- `cleanupOrphanedPreviews()` - Entfernt nicht mehr verwendete Previews
- `getPreviewPath(originalFileName)` - Gibt Preview-Pfad zurück
**Optionen:**
```javascript
{
width: 800, // Max-Breite in px
quality: 85, // JPEG-Qualität
format: 'jpeg', // 'jpeg' oder 'webp'
withoutEnlargement: true // Keine Vergrößerung kleiner Bilder
}
```
#### 1.2 Upload-Route erweitern
**Datei:** `backend/src/routes/upload.js` & `backend/src/routes/batchUpload.js`
- Nach erfolgreichem Upload: Preview-Generierung triggern
- Preview-Pfad in DB speichern
- Fehlerbehandlung: Bei Preview-Fehler Upload trotzdem erfolgreich
#### 1.3 DB-Schema Migration
**Datei:** `backend/src/database/migrations/003_add_preview_path.sql` (NEU)
```sql
-- Migration 003: Add preview_path column
ALTER TABLE images ADD COLUMN preview_path TEXT;
CREATE INDEX IF NOT EXISTS idx_images_preview_path ON images(preview_path);
```
**Datei:** `backend/src/database/DatabaseManager.js`
- Erweitere `initDatabase()` um Migration-Support
- Auto-run Migrations beim Start
#### 1.4 API-Endpunkte erweitern
**Bestehende Endpoints anpassen:**
- `GET /groups` - Rückgabe mit `previewPath` für jedes Bild
- `GET /groups/:groupId` - Rückgabe mit `previewPath`
- `GET /moderation/groups` - Rückgabe mit `previewPath`
**Neue Endpoints (optional):**
- `POST /groups/:groupId/regenerate-previews` - Regeneriert Previews für Gruppe
- `GET /previews/:fileName` - Serve Preview-Bilder (analog zu `/upload/:fileName`)
#### 1.5 Constants & Config
**Datei:** `backend/src/constants.js`
```javascript
const PREVIEW_FS_DIR = 'data/previews';
const PREVIEW_CONFIG = {
width: 800,
quality: 85,
format: 'jpeg'
};
```
---
### Phase 2: Backend - Batch-Migration bestehender Bilder (2-4h)
#### 2.1 Migration-Script
**Datei:** `backend/src/scripts/generatePreviewsForExisting.js`
- Liest alle Bilder aus DB ohne `preview_path`
- Generiert Previews für alle bestehenden Bilder
- Aktualisiert DB mit Preview-Pfaden
- Progress-Logging
**Ausführung:**
```bash
node backend/src/scripts/generatePreviewsForExisting.js
```
Oder als Express-Endpoint für Admin:
- `POST /admin/migrate-previews` (mit Basic Auth)
---
### Phase 3: Frontend - Preview-Nutzung (3-6h)
#### 3.1 API-Response erweitern
**Typ-Definitionen (optional):**
```typescript
interface Image {
id: number;
fileName: string;
originalName: string;
filePath: string; // Original-Bild
previewPath?: string; // NEU: Preview-Bild
uploadOrder: number;
fileSize: number;
mimeType: string;
}
```
#### 3.2 Component Updates
**Dateien zu ändern:**
- `frontend/src/Components/ComponentUtils/GroupCard.js`
- `frontend/src/Components/Pages/GroupsOverviewPage.js`
- `frontend/src/Components/Pages/ModerationGroupsPage.js`
**Logik:**
```javascript
const imageSrc = image.previewPath || image.filePath;
// Fallback auf Original, falls Preview fehlt
```
#### 3.3 Slideshow beibehält Original
**Datei:** `frontend/src/Components/Pages/SlideshowPage.js`
- **Keine Änderung** - Slideshow nutzt weiterhin `filePath` (Original)
---
### Phase 4: Testing & Optimierung (2-4h)
#### 4.1 Unit Tests
- `ImagePreviewService.test.js` - Service-Logik
- Test mit verschiedenen Bildformaten (JPEG, PNG)
- Error-Handling Tests
#### 4.2 Integration Tests
- Upload → Preview-Generierung → DB-Update
- API-Response enthält `previewPath`
- Frontend lädt Preview-Bilder
#### 4.3 Performance-Messung
- Vergleich Ladezeiten: Original vs. Preview
- Bundle-Size (Sharp Library Impact)
- Memory-Usage bei Batch-Generierung
#### 4.4 Cleanup & Docs
- `README.md` Update mit Preview-Feature
- `CHANGELOG.md` Eintrag
- Code-Kommentare & JSDoc
---
## ⏱️ Zeitschätzung
| Phase | Aufgabe | Geschätzt |
|-------|---------|-----------|
| 1.1 | ImagePreviewService | 2-3h |
| 1.2 | Upload-Route erweitern | 1-2h |
| 1.3 | DB-Migration | 1h |
| 1.4 | API-Endpoints | 1-2h |
| 1.5 | Config/Constants | 0.5h |
| 2.1 | Batch-Migration Script | 2-4h |
| 3.1-3.3 | Frontend Updates | 3-6h |
| 4.1-4.4 | Testing & Docs | 2-4h |
| **Gesamt** | | **12-22h** |
**Realistische Schätzung:** 2-3 Arbeitstage
---
## 🚀 Deployment-Strategie
### Schritt 1: Backend-Deploy mit Preview-Generierung
- Deploy neuer Backend-Code
- DB-Migration läuft automatisch beim Start
- Neue Uploads erhalten automatisch Previews
### Schritt 2: Batch-Migration (einmalig)
```bash
docker exec image-uploader-backend node src/scripts/generatePreviewsForExisting.js
```
oder via Admin-Endpoint
### Schritt 3: Frontend-Deploy
- Deploy Frontend mit Preview-Support
- Fallback auf Original-Bilder bleibt aktiv
### Rollback-Plan
- Preview-Feature ist opt-in (Fallback auf `filePath`)
- Bei Problemen: Frontend-Rollback ohne Backend-Änderung nötig
---
## 📊 Erwartete Verbesserungen
### Dateigrößen (Beispiel)
- **Original JPEG (3000x2000px):** ~2-3 MB
- **Preview JPEG (800x533px, 85%):** ~80-150 KB
- **Einsparung:** ~95%
### Ladezeiten (Galerie mit 20 Bildern)
- **Vorher:** 20 × 2.5 MB = 50 MB
- **Nachher:** 20 × 100 KB = 2 MB
- **Verbesserung:** ~96% schneller
---
## ⚠️ Risiken & Mitigation
### Risiko 1: Sharp Build-Fehler in Docker
**Mitigation:**
- Alpine-kompatible Sharp-Version testen
- Falls nötig: `python3`, `make`, `g++` in Dockerfile hinzufügen
### Risiko 2: Disk-Space Verdopplung
**Mitigation:**
- Previews sind ~5% der Original-Größe
- Cleanup-Script für verwaiste Previews
- Optional: alte Previews nach X Tagen löschen
### Risiko 3: CPU-Last bei Batch-Migration
**Mitigation:**
- Batch-Processing mit Chunk-Size (z.B. 10 Bilder parallel)
- Progress-Logging
- Optional: Background-Job Queue (Bull, Agenda)
---
## 🔄 Zukünftige Erweiterungen
- **WebP-Support:** Kleinere Dateien, bessere Compression
- **Responsive Previews:** Mehrere Größen (400px, 800px, 1200px)
- **Lazy-Loading:** Intersection Observer für On-Demand-Loading
- **CDN-Integration:** Previews auf S3/CloudFront auslagern
- **Image-Optimization:** Auto-Rotation (EXIF), Strip Metadata
---
## 📝 Acceptance Criteria
- [ ] Neue Uploads generieren automatisch Previews
- [ ] Bestehende Bilder haben Previews nach Migration
- [ ] Galerie-Views laden Preview-Bilder (keine Originals)
- [ ] Slideshow lädt weiterhin Original-Bilder
- [ ] API liefert sowohl `filePath` als auch `previewPath`
- [ ] Fallback auf Original funktioniert, wenn Preview fehlt
- [ ] Ladezeit-Verbesserung messbar (>80%)
- [ ] Tests bestehen (Unit + Integration)
- [ ] Dokumentation aktualisiert
---
**Erstellt am:** 29. Oktober 2025
**Zuletzt aktualisiert:** 29. Oktober 2025