React DevTools Profiler: Flame Graphs richtig interpretieren
AI generated
{ }
React · Performance · DevTools
React DevTools Profiler
Flame Graphs richtig lesen statt nur bunte Balken anzustarren

Der Profiler-Tab der React DevTools zeigt bei jedem Commit einen Flame Graph, aber die Faerbung allein sagt wenig aus. Wer Commit-Dauer, Ranked Chart und die Why-did-this-render Anzeige richtig kombiniert, findet echte Bottlenecks statt an Symptomen zu doktern.

14 Min. Lesezeit React DevTools Profiler Flame Graph

1. Was der Profiler-Tab ueberhaupt aufzeichnet

Der Profiler-Tab der React DevTools zeichnet jeden Commit auf, also jeden Moment, in dem React einen berechneten Render-Baum tatsaechlich in das DOM uebertraegt. Ein Commit ist dabei nicht dasselbe wie ein einzelner State-Update-Aufruf: React kann mehrere State-Updates zu einem Commit zusammenfassen (Batching), sodass ein Commit im Profiler oft das Ergebnis mehrerer setState-Aufrufe innerhalb eines Event-Zyklus repraesentiert. Wer im Profiler nach jedem einzelnen Klick genau einen Commit erwartet, wird von der Realitaet oft ueberrascht.

Zu jedem Commit speichert der Profiler eine Zeitleiste am oberen Rand mit einem Balken pro Commit, dessen Hoehe grob die Render-Dauer widerspiegelt, sowie darunter den eigentlichen Flame Graph fuer den aktuell ausgewaehlten Commit. Die Aufnahme muss aktiv gestartet werden, bevor die zu untersuchende Interaktion ausgefuehrt wird, und produktive Builds ohne Profiling-Flag liefern in aelteren React-Versionen keine sinnvollen Timing-Daten, weshalb fuer aussagekraeftige Messungen ein Profiling-faehiger Build noetig ist.

2. Den Flame Graph selbst lesen

Im Flame Graph steht jede Zeile fuer eine Ebene im Komponentenbaum, jeder Balken fuer eine einzelne Komponente, und die Breite des Balkens zeigt an, wie viel Zeit fuer das Rendern dieser Komponente und ihrer Kinder gebraucht wurde, relativ zu den anderen Komponenten im selben Commit. Eine Komponente, die grau statt farbig eingefaerbt ist, wurde in diesem Commit ueberhaupt nicht neu gerendert, React hat sie einfach uebersprungen, was bereits ein guter erster Hinweis darauf ist, wo im Baum die eigentliche Arbeit stattfand.

Die Faerbung selbst folgt einer Farbskala von Gelb ueber Orange bis hin zu einem satten Blau oder Gruen: gelbliche und orangene Toene markieren Komponenten mit ueberdurchschnittlich hoher Render-Zeit innerhalb des Commits, waehrend gruene oder blaue Toene fuer schnelle Komponenten stehen. Wichtig dabei ist, dass die Farbe relativ zum aktuell betrachteten Commit berechnet wird, nicht absolut: Eine Komponente kann in einem schnellen Commit gelb erscheinen, obwohl ihre absolute Render-Zeit niedriger ist als dieselbe Komponente in einem insgesamt langsameren Commit, wo sie gruen eingefaerbt ist.

3. Commit-Dauer und die Zeitleiste richtig einordnen

Am oberen Rand des Profiler-Tabs zeigt die Commit-Uebersicht einen Balken pro aufgezeichnetem Commit, wobei die Hoehe die relative Render-Dauer im Vergleich zu den anderen aufgezeichneten Commits darstellt. Ein besonders hoher Balken lohnt sich als erste Anlaufstelle, aber die absolute Zahl in Millisekunden, die beim Ueberfahren mit der Maus angezeigt wird, ist die eigentlich relevante Information, weil ein Commit von zwei Millisekunden auf schnellen Geraeten selbst als hoechster Balken in der Uebersicht meist irrelevant bleibt.

Ein haeufiger Denkfehler ist, ausschliesslich auf die Gesamtdauer eines Commits zu schauen und die Verteilung innerhalb des Commits zu ignorieren. Zwei Commits mit identischer Gesamtdauer koennen voellig unterschiedliche Ursachen haben: einmal eine einzelne, teure Komponente, die den Grossteil der Zeit beansprucht, das andere Mal Dutzende kleine Komponenten, die alle unnoetig neu rendern und sich in Summe zur selben Zeit addieren. Nur der Blick in den Flame Graph selbst unterscheidet diese beiden Faelle, die jeweils eine voellig andere Optimierung erfordern.

4. Warum wurde diese Komponente gerendert

Klickt man im Flame Graph auf eine einzelne Komponente, zeigt der rechte Seitenbereich der DevTools unter anderem den Abschnitt 'Why did this render', der die konkrete Ursache des Renders benennt: geaenderte Props, geaenderter State, ein Context-Update oder ein Render des Elternteils ohne eigentliche Notwendigkeit. Diese Anzeige ist der direkteste Weg, um zwischen einem berechtigten Render, weil sich tatsaechlich relevante Daten geaendert haben, und einem unnoetigen Render, weil das Elternteil einfach immer alle Kinder neu rendert, zu unterscheiden.

Bei geaenderten Props listet die Anzeige sogar auf, welche konkreten Prop-Namen sich veraendert haben, was besonders bei Komponenten mit vielen Props hilft, den genauen Ausloeser einzugrenzen, statt raten zu muessen. In aktuellen React-Versionen ist diese Funktion standardmaessig aktiviert, in aelteren Versionen musste die Option 'Record why each component rendered while profiling' im Einstellungsdialog der DevTools vor der Aufnahme manuell aktiviert werden, da sie einen kleinen zusaetzlichen Overhead verursacht.

5. Der Ranked Chart als Alternative zum Flame Graph

Neben dem Flame Graph bietet der Profiler eine zweite Ansicht, den Ranked Chart, der alle Komponenten eines Commits nach ihrer eigenen Render-Dauer sortiert auflistet, von der langsamsten bis zur schnellsten, unabhaengig von ihrer Position im Komponentenbaum. Waehrend der Flame Graph gut zeigt, wie sich Zeit hierarchisch durch den Baum verteilt, ist der Ranked Chart die schnellere Ansicht, um direkt die teuerste einzelne Komponente in einem Commit zu identifizieren, ohne sich durch mehrere verschachtelte Ebenen klicken zu muessen.

Ein wichtiger Unterschied bei der Interpretation: Der Ranked Chart zeigt die 'self time' jeder Komponente, also die Zeit, die ausschliesslich fuer die Komponente selbst aufgewendet wurde, ohne die Zeit ihrer Kinder. Eine Elternkomponente kann deshalb im Flame Graph riesig wirken, weil sie viele teure Kinder umschliesst, waehrend sie im Ranked Chart weit unten steht, weil ihre eigene Render-Logik trivial ist. Beide Ansichten gemeinsam zu nutzen liefert ein vollstaendigeres Bild als jede fuer sich allein.

6. Profiler-Einstellungen fuer aussagekraeftigere Messungen

Im Zahnrad-Symbol des Profiler-Tabs verstecken sich mehrere Optionen, die die Aussagekraft der Messung deutlich verbessern: 'Highlight updates when components render' faerbt Komponenten waehrend der normalen Nutzung (ausserhalb der Aufnahme) kurz ein, sobald sie neu rendern, was fuer eine schnelle visuelle Kontrolle nuetzlich ist, bevor man ueberhaupt eine formale Profiler-Session startet. 'Hide commits below X ms' blendet in der Commit-Uebersicht irrelevant kurze Commits aus, damit sich die Zeitleiste auf die tatsaechlich relevanten Ausreisser konzentriert.

Fuer produktionsnahe Messungen ist zusaetzlich entscheidend, mit einem Profiling-faehigen Production Build zu testen statt mit dem Development Build, da Development Builds durch zusaetzliche Warnungen, PropTypes-Checks und Konsistenzpruefungen deutlich langsamer sind und die absoluten Zahlen im Profiler dadurch verzerrt, wenn auch nicht komplett unbrauchbar, werden. React bietet dafuer ein spezielles 'profiling' Build-Target, das die Produktionsoptimierungen behaelt, aber die fuer den Profiler noetigen Timing-Marker zusaetzlich einbaut.

7. Ein konkreter Debugging-Workflow

Ein typischer Workflow beginnt mit dem Start der Aufnahme, dem Ausfuehren der zu untersuchenden Interaktion, etwa dem Tippen in ein Suchfeld, und dem anschliessenden Stoppen der Aufnahme. Danach identifiziert man in der Commit-Uebersicht die auffaelligsten Balken, wechselt fuer jeden davon zwischen Flame Graph und Ranked Chart, um sowohl die hierarchische Verteilung als auch die teuerste Einzelkomponente zu sehen, und klickt dann gezielt auf die verdaechtigen Komponenten, um ueber Why-did-this-render die genaue Ursache zu bestaetigen.

Stellt sich zum Beispiel heraus, dass eine Listenkomponente bei jedem Tastendruck komplett neu rendert, obwohl sich nur das Suchfeld selbst aendert, deutet Why-did-this-render meist auf ein geaendertes Prop hin, das eigentlich stabil sein sollte, etwa eine inline definierte Callback-Funktion oder ein inline erzeugtes Options-Objekt. Die Loesung ist dann typischerweise, die betroffene Funktion mit useCallback zu stabilisieren oder die Liste selbst mit memo zu umschliessen, damit ein unveraendertes Props-Objekt den erneuten Render tatsaechlich verhindert.


// Vorher: SearchResults rendert bei jedem Tastendruck neu,
// weil onSelect bei jedem Render von SearchPage neu erzeugt wird
function SearchPage() {
  const [query, setQuery] = useState('');

  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <SearchResults
        query={query}
        onSelect={(item) => console.log(item)} // neue Referenz pro Render
      />
    </>
  );
}

// Nachher: onSelect stabilisiert, SearchResults memoisiert
const SearchResults = memo(function SearchResults({ query, onSelect }) {
  // ...
});

function SearchPage() {
  const [query, setQuery] = useState('');
  const handleSelect = useCallback((item) => console.log(item), []);

  return (
    <>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <SearchResults query={query} onSelect={handleSelect} />
    </>
  );
}

8. Haeufige Fallstricke bei der Interpretation

Ein haeufiger Fallstrick ist, die Farbskala als absolute Aussage ueber Performance misszuverstehen: Da sie relativ zum jeweiligen Commit berechnet wird, ist ein durchgehend orange gefaerbter Commit nicht zwangslaeufig ein Problem, wenn die absolute Gesamtdauer trotzdem im niedrigen einstelligen Millisekundenbereich liegt. Wer nur auf Farbe achtet statt auf die tatsaechlichen Millisekundenwerte, jagt schnell Phantom-Probleme, die im echten Nutzererlebnis niemals spuerbar waeren.

Ein zweiter Fallstrick betrifft das Testen im Development-Modus: Manche Effekte, insbesondere durch React Strict Mode verursachte doppelte Renders in der Entwicklung, tauchen im Profiler als zusaetzliche Commits auf, die in Produktion gar nicht existieren. Wer eine Profiler-Session im Strict Mode aufzeichnet, sollte diese doppelten Commits bewusst herausrechnen und sich bei der finalen Bewertung auf einen Profiling-Build ohne Strict-Mode-Verdopplung verlassen, um keine falschen Schlussfolgerungen ueber die tatsaechliche Produktionsperformance zu ziehen.

9. Die wichtigsten Profiler-Werkzeuge im Ueberblick

Die React DevTools bieten mit Flame Graph, Ranked Chart, Commit-Uebersicht und Why-did-this-render vier komplementaere Werkzeuge, die jeweils eine andere Frage beantworten: wie verteilt sich Zeit im Baum, welche einzelne Komponente ist am teuersten, welcher Commit ist insgesamt auffaellig, und warum genau hat eine bestimmte Komponente ueberhaupt neu gerendert. Wer alle vier kombiniert, statt sich auf eines zu verlassen, findet Performance-Probleme systematisch statt zufaellig.

Die folgende Tabelle fasst zusammen, welches Werkzeug fuer welche Fragestellung am besten geeignet ist und worauf man bei der Interpretation jeweils achten sollte, damit die Farbskala und die Balkenhoehen nicht zu falschen Schlussfolgerungen fuehren.

Werkzeug Beantwortet Achtung bei Typischer Einstieg
Commit-Uebersicht Welcher Commit ist insgesamt auffaellig Relative Balkenhoehe, absolute ms pruefen Hoechsten Balken anklicken
Flame Graph Wie verteilt sich Zeit hierarchisch im Baum Farbe ist relativ zum Commit, nicht absolut Breite Balken auf oberer Ebene
Ranked Chart Welche einzelne Komponente ist am teuersten Zeigt self time ohne Kinderzeit Oberste Zeile der Liste
Why did this render Warum genau wurde neu gerendert Muss teils vorab aktiviert werden Auf verdaechtige Komponente klicken
Highlight updates Welche Komponenten rendern ausserhalb der Aufnahme Nur visuell, keine Zahlen Waehrend normaler Nutzung beobachten

Mironsoft

React-Architektur, Performance und Magento-Frontend-Integration

React-Frontends, die schnell bleiben statt mit jedem Feature langsamer zu werden?

Wir prüfen bestehende React-Anwendungen auf unnötige Re-Renders, aufgeblähte Bundles und fragile State-Verwaltung und bauen daraus ein Frontend, das performant bleibt und sich sauber an Magento oder andere Backends anbindet.

Performance-Audit

Re-Renders, Bundle-Größe und Ladezeiten systematisch messen und beheben.

State-Architektur

Context, Zustand und Server State sauber trennen statt alles in einen Topf zu werfen.

Magento-Integration

GraphQL- oder REST-Anbindung an Magento robust und typsicher aufbauen.

10. Zusammenfassung

React Profiler Flame Graphs: Das Wichtigste auf einen Blick

Farbe ist relativ

Die Flame Graph Faerbung bezieht sich immer auf den aktuell gewaehlten Commit, nicht auf einen absoluten Schwellenwert.

Ranked Chart nutzen

Fuer die schnellste Identifikation der teuersten Einzelkomponente ist der Ranked Chart oft direkter als der Flame Graph.

Why did this render

Zeigt die konkrete Ursache eines Renders: geaenderte Props, State, Context oder Render des Elternteils.

Profiling Build nutzen

Development Builds verzerren absolute Zahlen, ein spezieller Profiling Build liefert produktionsnahe Werte.

11. FAQ: React Profiler Flame Graphs: Das Wichtigste auf einen Blick

1Was bedeutet die Farbe eines Balkens im Flame Graph genau?
Die Farbe zeigt die relative Render-Dauer einer Komponente im Vergleich zu allen anderen Komponenten im selben Commit, von gruen oder blau fuer schnell bis gelb oder orange fuer langsam. Sie ist keine absolute Aussage, ein orange gefaerbter Balken in einem insgesamt sehr schnellen Commit kann trotzdem im niedrigen Millisekundenbereich liegen.
2Warum ist eine Komponente im Flame Graph grau eingefaerbt?
Graue Komponenten wurden in diesem Commit nicht neu gerendert, React hat sie uebersprungen, weil sich weder ihre Props noch ihr State geaendert haben oder weil sie durch memo geschuetzt sind. Sie erscheinen trotzdem im Baum, damit die Struktur nachvollziehbar bleibt.
3Was ist der Unterschied zwischen Flame Graph und Ranked Chart?
Der Flame Graph zeigt die hierarchische Verteilung der Render-Zeit entlang des Komponentenbaums, der Ranked Chart listet alle Komponenten eines Commits flach nach ihrer eigenen Render-Zeit sortiert auf, unabhaengig von ihrer Position im Baum. Der Ranked Chart ist meist schneller, um die teuerste Einzelkomponente zu finden.
4Wie aktiviere ich Why did this render in den DevTools?
In aktuellen React-Versionen ist die Anzeige meist standardmaessig verfuegbar, sobald man eine Komponente im Flame Graph anklickt. In aelteren Versionen muss zuerst im Zahnrad-Symbol des Profiler-Tabs die Option Record why each component rendered while profiling aktiviert werden, bevor eine neue Aufnahme gestartet wird.
5Warum unterscheiden sich meine Messwerte zwischen Development und Production?
Development Builds enthalten zusaetzliche Warnungen, Konsistenzpruefungen und teils doppelte Renders durch Strict Mode, was die absoluten Zeiten deutlich erhoeht. Fuer realistische Messungen sollte ein spezieller Profiling Production Build verwendet werden, der die Produktionsoptimierungen behaelt, aber die Profiler-Timing-Marker zusaetzlich enthaelt.
6Was bedeutet self time im Ranked Chart?
Self time ist die Zeit, die eine Komponente ausschliesslich fuer ihre eigene Render-Arbeit gebraucht hat, ohne die Zeit ihrer Kindkomponenten. Eine Elternkomponente mit trivialer eigener Logik kann deshalb im Ranked Chart weit unten stehen, obwohl sie im Flame Graph wegen ihrer teuren Kinder gross wirkt.
7Muss ich vor jeder Profiler-Aufnahme die Aufnahme manuell starten?
Ja, der Profiler zeichnet nur auf, waehrend die Aufnahme aktiv ist, und die zu untersuchende Interaktion muss innerhalb dieses Zeitfensters ausgefuehrt werden. Nach dem Stoppen der Aufnahme lassen sich alle aufgezeichneten Commits im Nachhinein beliebig oft durchklicken.
8Warum sehe ich im Strict Mode doppelt so viele Commits?
React Strict Mode fuehrt in der Entwicklung bestimmte Funktionen, darunter teilweise auch Renders, absichtlich zweimal aus, um Seiteneffekte in unreinen Komponenten aufzudecken. Diese zusaetzlichen Commits existieren nur in der Entwicklungsumgebung und sollten bei der Bewertung der echten Produktionsperformance nicht mitgezaehlt werden.
9Kann ich Hide commits below X ms auch nachtraeglich auf eine bestehende Aufnahme anwenden?
Ja, die Einstellung filtert die Anzeige der bereits aufgezeichneten Commits in der Uebersicht, sie muss nicht vor der Aufnahme gesetzt werden. Sie ist besonders hilfreich bei langen Sessions mit vielen kurzen, irrelevanten Commits, die die Zeitleiste sonst unuebersichtlich machen.
10Lohnt sich der Profiler auch bei kleinen Anwendungen ohne erkennbare Performance-Probleme?
Ja, gerade weil unnoetige Re-Renders oft unbemerkt bleiben, solange die Anwendung klein ist, lohnt sich ein gelegentlicher Blick in den Profiler frueh im Projekt. Muster wie inline erzeugte Callback-Funktionen oder fehlende Memoisierung lassen sich so erkennen, bevor sie bei wachsender Datenmenge zu spuerbaren Problemen werden.