- Startseite
- Skills
- Code-Review
- Performance-Code-Review
Performance-Code-Review
Code auf Performance pruefen: O(n²)-Schleifen, Speicherlecks, unnoetige Renders und langsame Abfragen.
Das Problem
Performance-Bugs loesen selten Fehler aus — sie machen nur alles langsamer. Eine verschachtelte Schleife, die mit 100 Elementen funktioniert, kriecht bei 10.000. Eine React-Komponente rendert 47 Mal pro Tastendruck, weil ein Callback bei jedem Render neu erstellt wird. Eine Datenbankabfrage holt 50 verknuepfte Datensaetze einzeln statt in einem Join. Diese Probleme werden unbemerkt ausgeliefert, bis Nutzer sich beschweren oder Server unter Last zusammenbrechen.
Der Prompt
Pruefe den folgenden Code auf Performance-Probleme. Handle als Performance-Engineer, der ein Produktionssystem unter hoher Last profiliert.
SPRACHE/FRAMEWORK: [z.B. TypeScript/React, Python/Django, Rust]
ERWARTETE SKALIERUNG: [z.B. 10k gleichzeitige Nutzer, 1M Datenbankzeilen, mobile Geraete]
CODE:
[Code hier einfuegen]
Analysiere in diesen Performance-Dimensionen:
1. **Algorithmische Komplexitaet**
- O(n^2) oder schlimmere Operationen identifizieren (verschachtelte Schleifen, wiederholte Array-Scans)
- Operationen markieren, die Set/Map fuer O(1)-Lookups statt array.find/includes nutzen sollten
- Redundante Berechnungen pruefen, die gecacht/memoisiert werden koennten
2. **Speicher**
- Grosse Objektallokationen innerhalb von Schleifen oder Hot Paths
- Fehlende Bereinigung (Event Listener, Intervalle, Subscriptions)
- Unbegrenzte Arrays/Caches, die ohne Limit wachsen
3. **Rendering (Frontend)**
- Komponenten, die ohne Prop-Aenderungen neu rendern
- Fehlendes useMemo/useCallback fuer teure Berechnungen oder Callback-Props
- Layout Thrashing (DOM lesen → DOM schreiben → DOM lesen)
4. **I/O und Netzwerk**
- N+1-Query-Patterns (verknuepfte Daten in Schleifen abfragen)
- Fehlende Paginierung bei Listen-Endpunkten
- Sequenzielle Awaits, die Promise.all sein koennten
- Fehlende Request-Deduplizierung oder Caching
5. **Bundle und Laden**
- Grosse Imports, die lazy-loaded werden koennten
- Synchrone Operationen, die den Main Thread blockieren
- Fehlende Code-Splitting-Moeglichkeiten
Fuer jedes Problem liefere:
- **Ort**: Datei und Zeile
- **Auswirkung**: Quantifizierte Schaetzung (z.B. "47 Re-Renders pro Tastendruck")
- **Schweregrad**: Kritisch / Moderat / Minor
- **Fix**: Optimierter Code-Ersatz
- **Tradeoff**: Lesbarkeits- oder Komplexitaetskosten der Optimierung
Beispielausgabe
## Performance-Review: 5 Probleme gefunden
### Kritisch: N+1-Query-Pattern
Ort: src/api/orders.ts:23
Auswirkung: 1 Query pro Bestellposition. Bei 200 Bestellungen × 5 Positionen = 1.000 Queries statt 2.
Fix:
const orderIds = orders.map(o => o.id);
const items = await db.query("SELECT * FROM items WHERE order_id IN (?)", [orderIds]);
Tradeoff: Etwas mehr Speicher fuer alle Items gleichzeitig. Bei dieser Groesse vernachlaessigbar.
### Moderat: Unnoetige Re-Renders
Ort: src/components/SearchResults.tsx:15
Auswirkung: Jeder Tastendruck rendert alle 50 Ergebniskarten neu, weil die Filterfunktion neu erstellt wird.
Fix: Mit useMemo wrappen:
const filtered = useMemo(() => results.filter(r => r.name.includes(query)), [results, query]);
Wann verwenden
Vor dem Deployment von Features ausfuehren, die Listen, nutzergenerierte Inhalte oder Datenbankabfragen in grossem Massstab verarbeiten. Besonders wertvoll beim Uebergang vom Prototyp (100 Datensaetze) zur Produktion (100.000 Datensaetze) — Performance-Patterns, die bei kleinem Massstab funktionieren, brechen bei realem Massstab oft zusammen.
Profi-Tipps
- Skalierung angeben — “1.000 Nutzer” und “1.000.000 Nutzer” erfordern voellig unterschiedliche Optimierungsstrategien. Immer das erwartete Datenvolumen einbeziehen.
- Big-O-Annotationen anfordern — “Annotiere jede Funktion mit ihrer Zeit- und Platzkomplexitaet” fuer eine Komplexitaetskarte des Codes.
- Erst profilieren, dann optimieren — dieses Review nutzen, um Verdaechtige zu identifizieren, dann mit echten Profiling-Daten bestaetigen.