Back

Code-Metriken erklärt: Was ist zyklomatische Komplexität?

Code-Metriken erklärt: Was ist zyklomatische Komplexität?

Du prüfst einen Pull Request und eine Funktion ist mittlerweile so groß geworden, dass sie acht verschiedene Bedingungen abdeckt – Benutzerrollen, Feature Flags, Edge Cases, Fallbacks. Die Tests laufen durch. Sie funktioniert. Aber irgendetwas stimmt nicht. Dieses Gefühl hat einen Namen – und eine Zahl.

Die zyklomatische Komplexität ist eine Code-Qualitätsmetrik, die misst, wie viele unabhängige Ausführungspfade durch eine Funktion existieren. Je höher die Zahl, desto mehr Verzweigungslogik enthält dein Code – und desto schwieriger wird er zu lesen, zu testen und zu warten.

Wichtige Erkenntnisse

  • Die zyklomatische Komplexität zählt die Anzahl unabhängiger Pfade durch eine Funktion und liefert dir ein messbares Signal für Verzweigungslogik.
  • Du berechnest sie schnell, indem du bei 1 startest und für jede Verzweigungsanweisung wie if, &&, ||, case oder einen ternären Operator 1 hinzufügst.
  • Sie unterscheidet sich von der kognitiven Komplexität, die misst, wie schwer Code für einen Menschen zu lesen ist – und nicht, wie viele Pfade er enthält.
  • Tools wie ESLint und SonarQube können die Komplexität automatisch erfassen und Funktionen markieren, die einen konfigurierbaren Schwellenwert überschreiten.
  • Reduziere die Komplexität mit Guard Clauses, ausgelagerten Helfern, aussagekräftigen Boolean-Variablen und Lookup-Tabellen.

Wie die zyklomatische Komplexität berechnet wird

Die 1976 von Thomas McCabe entwickelte Metrik wird aus dem Kontrollflussgraphen einer Funktion abgeleitet. Die praxisrelevante Formel für eine einzelne zusammenhängende Komponente lautet:

M = E − N + 2P

Dabei ist E die Anzahl der Kanten, N die Anzahl der Knoten, P die Anzahl der zusammenhängenden Komponenten (in der Regel 1 bei einer einzelnen Funktion) und M der Komplexitätswert.

Für die meisten JavaScript-Entwickler ist eine manuelle Berechnung nicht nötig. Die Abkürzung: bei 1 starten und für jede Verzweigungsanweisung 1 hinzufügenif, else if, &&, ||, for, while, case, ternäre Operatoren und catch-Klauseln. Manche Tools berücksichtigen zusätzlich Konstrukte wie Optional Chaining, Default-Werte und Logical Assignment. Die genauen Berechnungsregeln können zwischen Tools wie ESLint und SonarQube leicht variieren.

Ein JavaScript-Beispiel: Wie Verzweigungen die Komplexität erhöhen

// Cyclomatic complexity: 1
function getDisplayName(user: User): string {
  return user.name;
}
// Cyclomatic complexity: 6
function getDisplayName(user: User | null): string {
  if (!user) return "Guest";                     // +1
  if (user.isAdmin) return "Admin";              // +1
  if (user.displayName) return user.displayName; // +1
  if (user.firstName && user.lastName)           // +1 (if) +1 (&&)
    return `${user.firstName} ${user.lastName}`;
  return user.email;
}

Jede Bedingung fügt eine Verzweigung hinzu. Mehr Verzweigungen bedeuten mehr zu testende Pfade – und mehr Möglichkeiten, dass eine zukünftige Änderung unerwartet etwas kaputtmacht.

Dieses Muster taucht im Frontend-Code ständig auf: in der Render-Logik von React-Komponenten, in Redux-Reducern mit vielen Action-Typen, in Formularvalidierungs-Handlern und in berechtigungsbasierten UI-Flows.

Zyklomatische Komplexität vs. kognitive Komplexität

Beides sind verwandte, aber unterschiedliche Metriken. Die zyklomatische Komplexität zählt strukturelle Verzweigungen – sie ist ein Signal für Testbarkeit. Die kognitive Komplexität (popularisiert durch SonarQube) misst, wie schwer Code für einen Menschen zu lesen ist, und gewichtet Verschachtelungen sowie nicht-linearen Flow stärker.

Eine Funktion kann eine niedrige zyklomatische Komplexität aufweisen und trotzdem schwer nachzuvollziehen sein – zum Beispiel bei tief verketteten Methodenaufrufen ohne Zwischenvariablen. Beide Metriken sind nützlich, und keine erzählt für sich allein die ganze Geschichte.

So misst du sie in deiner JavaScript-Codebasis

Zwei praxistaugliche Tools für Frontend-Teams:

  • ESLint-Regel complexity – markiert Funktionen oberhalb eines konfigurierbaren Schwellenwerts direkt im Editor
  • SonarQube / SonarCloud – berichtet sowohl die zyklomatische als auch die kognitive Komplexität über deine gesamte Codebasis

ESLint konfigurierst du so:

{
  "rules": {
    "complexity": ["warn", { "max": 10 }]
  }
}

Der Schwellenwert ist konfigurierbar – und sollte es auch sein. Ein Validierungs-Utility und ein Redux-Reducer brauchen nicht dieselbe Obergrenze. Passe Schwellenwerte an den Kontext deines Codes an, statt einer universellen Regel zu folgen.

Praktische Wege, unnötige Komplexität zu reduzieren

Wenn der Score einer Funktion ansteigt, helfen folgende Techniken:

  • Funktionen extrahieren – ziehe abgegrenzte Logik in benannte Helfer
  • Guard Clauses verwenden – kehre frühzeitig zurück, statt Bedingungen zu verschachteln
  • Bedingungen vereinfachen – ersetze komplexe Boolean-Ketten durch aussagekräftige Variablen
  • Lookup-Tabellen nutzen – ersetze lange switch-Anweisungen durch Objekte oder Map

Das Ziel ist nicht ein niedriger Score um seiner selbst willen. Es geht um Code, der leichter zu testen, leichter zu ändern und für den nächsten Entwickler leichter zu verstehen ist.

Fazit

Die zyklomatische Komplexität liefert dir ein konkretes, messbares Signal über die Verzweigungslogik in deinem Code. Nutze ESLint oder SonarQube, um sie zu erfassen, lege Schwellenwerte fest, die zu deiner Codebasis passen, und behandle steigende Werte als Anlass zum Refactoring – nicht als Krise. Kombiniere sie mit der kognitiven Komplexität, um ein vollständigeres Bild der Wartbarkeit zu erhalten.

FAQs

Eine gängige Faustregel ist, Funktionen bei einem Wert von höchstens 10 zu halten. Werte von 1 bis 10 gelten als handhabbar, 11 bis 20 deuten darauf hin, dass die Funktion komplex wird, und alles über 20 ist meist ein klarer Kandidat für ein Refactoring. Der passende Schwellenwert hängt vom Codetyp ab – passe ihn also an den Kontext deines Teams an.

Die zyklomatische Komplexität zählt jede Verzweigungsanweisung gleich, unabhängig davon, wie tief sie verschachtelt ist. Eine Funktion mit drei flachen if-Anweisungen und eine mit drei verschachtelten if-Anweisungen können denselben Wert haben. Das ist einer der Gründe, warum es die kognitive Komplexität gibt: Sie gewichtet Verschachtelungen stärker und spiegelt besser wider, wie schwer der Code zu lesen ist.

Nicht immer. Ein hoher Wert signalisiert, dass eine Funktion einen genaueren Blick verdient – doch manche Logik ist von Natur aus verzweigungslastig, etwa Parser, Zustandsautomaten oder Validierungs-Pipelines. Nutze die Metrik als Anstoß für eine Überprüfung, nicht als strikte Regel. Wenn die Funktion gut getestet, klar geschrieben und stabil ist, kann ein Refactoring Risiken bergen, ohne echten Nutzen zu bringen.

Die Anzahl der Codezeilen misst die Größe, während die zyklomatische Komplexität Entscheidungspunkte misst. Eine 200-zeilige Funktion ohne Verzweigungen hat eine Komplexität von 1, während eine 20-zeilige Funktion voller Bedingungen einen deutlich höheren Wert erreichen kann. Die Komplexität ist ein besserer Indikator für Testbarkeit und Wartungsaufwand, weil sie widerspiegelt, wie viele Pfade deine Tests abdecken müssen.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay