# Performance-Richtlinien

## Übersicht

Diese Richtlinien beschreiben Best Practices für die Optimierung der Anwendungsleistung im Framework.

## Grundprinzipien

### 1. Frühe Optimierung vermeiden

- Code zuerst korrekt und lesbar schreiben
- Optimierungen auf Basis von Messungen durchführen
- Performance-Engpässe mit dem Profiler identifizieren

### 2. Caching strategisch einsetzen

- Ergebnisse teurer Operationen cachen
- Geeignete Cache-Invalidierungsstrategien implementieren
- Cache-Hierarchie nutzen (Memory → Filesystem → Datenbank)

```php
// Beispiel: Strategisches Caching
public function getExpensiveData(string $key): array
{
    $cacheKey = "data_{$key}";

    // Prüfen, ob Daten im Cache sind
    if ($this->cache->has($cacheKey)) {
        return $this->cache->get($cacheKey);
    }

    // Teure Operation durchführen
    $result = $this->performExpensiveOperation($key);

    // Ergebnis cachen mit angemessener TTL
    $this->cache->set($cacheKey, $result, 3600);

    return $result;
}
```

### 3. Lazy Loading

- Ressourcen erst bei Bedarf laden
- Schwere Abhängigkeiten verzögert initialisieren

```php
// Beispiel: Lazy Loading
private ?ExpensiveService $expensiveService = null;

private function getExpensiveService(): ExpensiveService
{
    if ($this->expensiveService === null) {
        $this->expensiveService = new ExpensiveService($this->config);
    }

    return $this->expensiveService;
}
```

### 4. Datenstrukturen optimieren

- Passende Datenstrukturen für den Anwendungsfall wählen
- Große Arrays vermeiden, wenn möglich Iteratoren oder Generatoren nutzen
- Bei großen Datenmengen paginieren

```php
// Beispiel: Generator statt Array
public function processLargeDataset(): Generator
{
    $handle = fopen($this->largeFile, 'r');

    while (($line = fgets($handle)) !== false) {
        yield $this->processLine($line);
    }

    fclose($handle);
}
```

## Spezifische Optimierungen

### Datenbankzugriffe

- Anzahl der Datenbankabfragen minimieren
- Indizes für häufige Abfragen
- N+1 Problem vermeiden durch Eager Loading
- Datenbankverbindungen poolen

### HTTP-Anfragen

- Statische Assets komprimieren und cachen
- HTTP/2 nutzen, wenn möglich
- Content-Kompression aktivieren
- Browser-Caching durch geeignete Header

### Speichernutzung

- Große Objekte nach Gebrauch freigeben (`unset()`)
- Zirkuläre Referenzen vermeiden
- Bei Dateiberarbeitung auf Streaming-Ansätze setzen

### Autoloading

- Composer-Autoloader in Produktionsumgebung optimieren
- Preloading für häufig verwendete Klassen nutzen

```php
// preload.php Beispiel
<?php

declare(strict_types=1);

// Häufig verwendete Klassen vorladen
require_once __DIR__ . '/Framework/Core/Application.php';
require_once __DIR__ . '/Framework/DI/Container.php';
require_once __DIR__ . '/Framework/Http/Request.php';
require_once __DIR__ . '/Framework/Http/Response.php';
```

## Monitoring und Profiling

### Performance messen

- Kritische Code-Pfade instrumentieren
- End-to-End Zeitmessungen durchführen

```php
// Beispiel: Performance-Messung
$startTime = microtime(true);

// Operation durchführen
$result = $this->performOperation();

$duration = microtime(true) - $startTime;
$this->logger->debug("Operation ausgeführt in {$duration}s");
```

### Automatisiertes Monitoring

- Performance-Regressions automatisch erkennen
- Regelmäßige Lasttests durchführen
- Kritische Pfade überwachen

## Umgebungsspezifische Optimierungen

### Entwicklung

- Debug-Tools aktivieren
- Performance-Optimierungen deaktivieren, die Debugging erschweren

### Produktion

- Opcache aktivieren und optimieren
- Fehlerbehandlung optimieren (keine Stack Traces)
- Logging auf nötige Informationen beschränken

```php
// Umgebungsspezifische Einstellungen
if ($environment === 'production') {
    ini_set('opcache.validate_timestamps', 0);
    ini_set('display_errors', 0);
    error_reporting(E_ERROR | E_WARNING | E_PARSE);
} else {
    ini_set('opcache.validate_timestamps', 1);
    ini_set('display_errors', 1);
    error_reporting(E_ALL);
}
```
