Wenn React mehr arbeitet als nötig
Erst messen, dann eingreifen: Der Profiler zeigt, welche Komponente wie oft und warum läuft, und erst danach ist die Frage nach Merkfunktionen überhaupt sinnvoll.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Merkfunktionen als Reflex verteuern die Anwendung, ohne sie schneller zu machen
Der übliche Ablauf: Jemand bemerkt eine träge Eingabe, hängt memo um ein paar Komponenten, verpackt Funktionen in useCallback und Objekte in useMemo. Danach fühlt sich nichts spürbar besser an, der Code ist aber schwerer zu lesen, und jede neue Eigenschaft muss ab sofort mitgedacht werden. Der Grund ist meistens derselbe: memo vergleicht die Eigenschaften nur oberflächlich, und wenn eine davon bei jedem Durchlauf neu entsteht, ist der Vergleich immer negativ und die Merkfunktion reiner Aufwand.
Der zweite Grund liegt in der Frage, was überhaupt teuer war. Ein erneuter Durchlauf einer kleinen Komponente kostet Bruchteile einer Millisekunde. Spürbar wird es, wenn dabei tausende Zeilen einer Tabelle neu erzeugt werden, wenn in jedem Durchlauf sortiert oder gefiltert wird oder wenn ein Effekt daran hängt, der eine Netzabfrage auslöst. Ohne Messung landet die Optimierung fast immer an der Stelle, die man verändern kann, und nicht an der, die Zeit kostet.
Dazu kommt eine falsche Erwartung: Ein Durchlauf ist kein Neuzeichnen. React vergleicht das Ergebnis mit dem vorherigen und fasst nur an, was sich unterscheidet. Wer die Zahl der Durchläufe zum Ziel erklärt, optimiert eine Größe, die für die wahrgenommene Geschwindigkeit oft gar nicht entscheidend ist.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Fünf Beobachtungen und was tatsächlich dahintersteckt
Die Symptome stammen aus Projekten, in denen die Ursache zunächst woanders vermutet wurde. Auffällig ist, wie oft die Lösung im Aufbau der Komponenten liegt und nicht in einer zusätzlichen Merkfunktion.
Symptom
Beim Tippen in ein Suchfeld ruckelt die ganze Seite, obwohl nur ein Buchstabe dazukommt.
Ursache
Der Wert des Feldes liegt in einer Komponente weit oben, damit läuft bei jedem Tastendruck der gesamte Baum darunter erneut, einschließlich der langen Liste.
Lösung
Zieh Feld und Wert in eine eigene kleine Komponente und gib nach oben nur weiter, was gebraucht wird. Wenn die gefilterte Liste wirklich teuer ist, halte die Eingabe reaktionsschnell und lass die Liste mit useDeferredValue nachziehen.
Symptom
Eine Komponente ist mit memo umschlossen und läuft trotzdem bei jedem Durchlauf der übergeordneten Komponente.
Ursache
Mindestens eine Eigenschaft ist ein Objekt, ein Array oder eine Funktion, die im Durchlauf neu entsteht. memo vergleicht flach, und zwei gleich aussehende Objekte sind für diesen Vergleich verschieden.
Lösung
Prüf die Eigenschaften einzeln und mach sie stabil: konstante Werte außerhalb der Komponente anlegen, abgeleitete Objekte mit useMemo festhalten, Rückrufe mit useCallback. Wenn dabei die halbe Datei aus Merkaufrufen besteht, ist der Compiler der bessere Weg.
Symptom
Nach dem Umbau auf Context rendert die halbe Anwendung neu, sobald sich ein einziges Feld ändert.
Ursache
Der Wert des Providers ist ein neues Objekt pro Durchlauf, und jede lesende Komponente hängt am gesamten Wert, nicht an einem Feld daraus.
Lösung
Teile den Context nach Änderungsrhythmus auf, etwa selten wechselnde Daten getrennt von den Funktionen zum Ändern, und halte den Wert mit useMemo stabil. Bei häufigen Änderungen ist ein externer Speicher mit gezieltem Lesen die passendere Lösung.
Symptom
Der Profiler zeigt zwei oder drei Durchläufe hintereinander für eine einzige Interaktion.
Ursache
Irgendwo wird Zustand während des Renderns oder in einem Effekt ohne Bedingung gesetzt. React rendert, der Effekt setzt Zustand, das löst den nächsten Durchlauf aus.
Lösung
Berechne abgeleitete Werte direkt im Render statt sie in einen Zustand zu schreiben. Die Regeln set-state-in-render und set-state-in-effect aus eslint-plugin-react-hooks melden genau diese beiden Muster, bevor sie im Profiler auffallen.
Symptom
Bei jedem Durchlauf der übergeordneten Komponente verliert ein Eingabefeld Fokus und Inhalt.
Ursache
Das ist kein erneuter Durchlauf, sondern ein Neuaufbau. Entweder wird die Komponente innerhalb einer anderen Komponente definiert, oder ihr key ändert sich, und React wirft den alten Baum weg.
Lösung
Definiere Komponenten immer auf oberster Ebene einer Datei und vergib keine Schlüssel, die sich bei jedem Durchlauf ändern, etwa aus Math.random oder dem Index nach dem Sortieren.
Fünf Schritte von der Beobachtung zur Ursache
- 01 Beobachtung festhalten: Welche Eingabe ruckelt, und ab wie vielen Daten?
- 02 Im Profiler aufzeichnen und die teuerste Aktualisierung heraussuchen.
- 03 Auslöser lesen: eigener Zustand, Context oder übergeordneter Durchlauf?
- 04 Struktur ändern: Zustand nach unten, Inhalte als children nach oben.
- 05 Erst danach memo, useMemo oder useCallback setzen und erneut messen.
Was du nach der Analyse belegen kannst
Die Reihenfolge entscheidet: erst sichtbar machen, welche Komponente wie oft läuft und wodurch, dann strukturell etwas ändern, und erst zuletzt an Merkfunktionen denken. In dieser Reihenfolge sind die meisten Fälle nach einer Stunde erledigt.
Die Auslöser eines Durchlaufs benennen
Eigener Zustand, ein geänderter Context-Wert oder ein Durchlauf der übergeordneten Komponente. Eine geänderte Eigenschaft allein löst ohne memo nichts aus, weil die übergeordnete Komponente ohnehin schon läuft.
Den Durchlauf messen statt schätzen
Der Profiler in den React Developer Tools zeichnet jede Aktualisierung auf und zeigt Dauer und Auslöser je Komponente. Damit steht fest, ob ein Durchlauf 0,2 oder 40 Millisekunden gekostet hat.
Zustand dorthin verschieben, wo er gebraucht wird
Ein Eingabefeld, dessen Wert ganz oben liegt, lässt bei jedem Tastendruck den ganzen Baum laufen. Eine eigene kleine Komponente um das Feld herum löst mehr Fälle als jede Merkfunktion.
Inhalte als children hereinreichen
Was als children übergeben wird, entsteht in der übergeordneten Komponente und läuft nicht neu, nur weil der Zustand der umgebenden Komponente wechselt. Das ist der billigste Schnitt durch einen Baum.
Merkfunktionen gezielt einsetzen
memo lohnt sich, wenn eine teure Komponente stabile Eigenschaften bekommt. useMemo lohnt sich bei einer nachweislich teuren Berechnung. useCallback lohnt sich, wenn die Funktion in eine solche Abhängigkeit fließt und sonst nirgends.
Den Compiler prüfen, bevor du von Hand merkst
Der React Compiler übernimmt seit Version 1.0 genau diese Arbeit automatisch und feiner, als es von Hand geht. Bevor du ein Projekt mit Merkaufrufen durchziehst, lohnt der Blick, ob er sich einschalten lässt.
KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Wann React eine Komponente erneut ausführt
Im Alltag sind es drei Auslöser. Erstens ändert sich der Zustand der Komponente selbst, über useState oder useReducer. Zweitens ändert sich ein Wert, den sie über useContext liest. Drittens läuft die übergeordnete Komponente erneut, dann laufen ihre Kinder mit, unabhängig davon, ob sich deren Eigenschaften geändert haben. Dazu kommt ein vierter Weg, sobald eine Speicherbibliothek im Spiel ist: Eine Komponente, die über useSyncExternalStore an einer Quelle außerhalb von React hängt, läuft, sobald sich ihr Ausschnitt dort ändert. Der dritte Punkt überrascht viele, ist aber die Voreinstellung: React vergleicht Eigenschaften nur dort, wo du es mit memo ausdrücklich verlangst.
Wichtig ist der Unterschied zwischen Durchlauf und Aktualisierung des DOM. Der Durchlauf erzeugt eine Beschreibung der Oberfläche, React vergleicht sie mit der vorherigen und ändert nur die Stellen, die sich unterscheiden. Ein Durchlauf ohne sichtbare Änderung ist deshalb billig, solange darin nichts Teures passiert. Genau deshalb ist die reine Zahl der Durchläufe keine gute Zielgröße.
Teuer wird ein Durchlauf durch drei Dinge: viele Kindkomponenten, aufwendige Berechnungen im Rumpf der Komponente und Effekte, die daran hängen. Der dritte Punkt ist der unangenehmste, weil ein überflüssiger Durchlauf dann nicht nur Rechenzeit kostet, sondern eine Netzabfrage auslöst oder ein Abonnement neu aufbaut.
Messen, bevor du etwas änderst
Die React Developer Tools bringen einen Profiler mit. Du zeichnest eine Interaktion auf und siehst danach je Aktualisierung, welche Komponenten gelaufen sind und wie lange sie gebraucht haben. In den Einstellungen des Profilers lässt sich zusätzlich aufzeichnen, warum eine Komponente gelaufen ist, also ob Eigenschaften, Zustand, Context oder die übergeordnete Komponente der Auslöser waren. Diese eine Einstellung beantwortet die meisten Fragen sofort.
Ein zweites Werkzeug aus demselben Paket ist die Option, aktualisierte Komponenten kurz hervorzuheben. Damit siehst du beim Tippen unmittelbar, ob wirklich nur das Eingabefeld oder die halbe Seite betroffen ist. Das ersetzt keine Messung, ist aber der schnellste Weg zu der Frage, wo du überhaupt genauer hinschauen musst.
Seit React 19.2 gibt es zusätzlich eigene Spuren im Leistungsprofil der Chrome-Entwicklerwerkzeuge: eine für die geplante Arbeit nach Priorität, eine für den Komponentenbaum mit Einhängen, Rendern und blockierten Abschnitten. Der Vorteil gegenüber dem React-Profiler ist, dass deine Komponenten im selben Bild stehen wie Netzabfragen, Skriptlaufzeit und Layout, und damit sichtbar wird, ob React überhaupt der Engpass war. Miss dabei möglichst in einem Produktionsbau, denn der Entwicklungsmodus ist deutlich langsamer und der strenge Modus führt Komponenten absichtlich doppelt aus, um fehlende Aufräumarbeiten zu zeigen. Wer diese doppelten Durchläufe für das Problem hält, optimiert etwas weg, das im Betrieb gar nicht existiert.
Was memo, useMemo und useCallback wirklich tun
memo umschließt eine Komponente und vergleicht vor dem Durchlauf ihre Eigenschaften flach mit den vorherigen. Sind alle identisch, überspringt React den Durchlauf samt Unterbaum. Der Vergleich prüft dabei Identität, nicht Inhalt: Ein neu erzeugtes Objekt mit denselben Feldern gilt als andere Eigenschaft. Deshalb wirkt memo nur zusammen mit stabilen Eigenschaften, und deshalb ist memo ohne diesen zweiten Schritt in vielen Projekten wirkungslos.
useMemo hält das Ergebnis einer Berechnung fest, solange sich die Abhängigkeiten nicht ändern. Zwei Gründe rechtfertigen das: eine wirklich teure Berechnung, etwa das Sortieren mehrerer tausend Datensätze, oder ein Wert, der als Eigenschaft in eine mit memo umschlossene Komponente oder als Abhängigkeit in einen Effekt fließt. useCallback ist derselbe Gedanke für Funktionen und hat genau denselben zweiten Grund.
Jeder dieser Aufrufe kostet etwas: Vergleichsaufwand, Speicher und Lesbarkeit. Eine Faustregel, die sich bewährt hat: Setz keine Merkfunktion, ohne vorher im Profiler gesehen zu haben, was sie einspart, und lass sie wieder weg, wenn der Unterschied nicht messbar ist. Was ohne Messung entsteht, wird später auch von niemandem mehr entfernt, weil keiner weiß, wofür es einmal da war.
Der Compiler nimmt dir die Handarbeit ab
Der React Compiler ist seit Oktober 2025 in Version 1.0 verfügbar. Er analysiert deine Komponenten beim Bauen und setzt die Merkarbeit automatisch, und zwar feiner, als es von Hand möglich wäre, weil er auch innerhalb einer Komponente unterscheidet, welcher Teil von welchem Wert abhängt. Er arbeitet ab React 17, wobei die Versionen 17 und 18 ein zusätzliches Laufzeitpaket brauchen, und lässt sich schrittweise einführen, also zunächst für einzelne Verzeichnisse.
Für bestehenden Code gilt eine wichtige Einschränkung: Vorhandene Aufrufe von useMemo und useCallback solltest du nicht pauschal entfernen, weil sie das Ergebnis der Übersetzung beeinflussen können. Der empfohlene Weg ist, den Compiler einzuschalten, das Verhalten zu prüfen und neue Komponenten ohne Handarbeit zu schreiben. In Next.js 16 ist die Unterstützung stabil, aber nicht voreingestellt, sie wird über eine Option in der Konfiguration eingeschaltet.
Unabhängig davon lohnt sich das zugehörige ESLint-Paket, denn die Prüfungen brauchen den Compiler gar nicht. eslint-plugin-react-hooks bringt in seiner empfohlenen Zusammenstellung Regeln mit, die typische Ursachen überflüssiger Durchläufe direkt beim Schreiben melden, etwa Zustandsänderungen im Render oder in einem Effekt.
Struktur schlägt Merkfunktion
Die wirksamsten Eingriffe verändern nicht das Verhalten von React, sondern den Zuschnitt der Komponenten. Zustand gehört so tief wie möglich: Ein Formularfeld, dessen Wert nur das Formular braucht, hat oben nichts verloren. Umgekehrt hilft es, Inhalte als children hereinzureichen, denn diese Elemente entstehen in der übergeordneten Komponente und laufen nicht mit, wenn sich der Zustand der umgebenden Komponente ändert.
Bei langen Listen ist die Antwort selten Merken, sondern weniger Zeilen im DOM. Ab einigen hundert Einträgen lohnt eine Bibliothek, die nur den sichtbaren Ausschnitt darstellt. Und bei teuren Filtern hilft es, die Eingabe von der Auswertung zu entkoppeln: Die Eingabe bleibt sofort reaktionsfähig, die Liste zieht mit einer niedrigeren Priorität nach, wofür React startTransition und useDeferredValue mitbringt.
Seit React 19.2 gibt es außerdem eine Komponente, die einen Unterbaum versteckt, ohne ihn wegzuwerfen: Der versteckte Bereich behält seinen Zustand, seine Effekte werden abgeräumt, und Aktualisierungen darin bekommen eine niedrige Priorität. Für Registerkarten und Ansichten, zwischen denen jemand hin und her wechselt, ist das der sauberere Weg als das übliche Ein- und Ausblenden über eine Bedingung, bei dem der Zustand jedes Mal verloren geht.
Dazu passende Kurse
Bei cmt lässt sich an einer eigenen Oberfläche nachvollziehen, wann React eine Komponente erneut ausführt , statt es aus Beispielen abzuleiten.
Der flache Vergleich, an dem memo scheitert, ist keine React-Eigenheit, sondern eine Frage der Sprache: wie Objekte und Funktionen in JavaScript verglichen werden .
Wie sicher bist du beim Thema wirklich?
Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.
Der passende Lernpfad
Wenn du nicht nur ein Thema abhaken, sondern eine Rolle ausfüllen willst, zeigt dir der Lernpfad die Kurse in der Reihenfolge, in der sie aufeinander aufbauen.
Dein Weg zum React Entwickler
Moderne Web-Produkte werden heute mit React gebaut. Wer es sauber beherrscht, arbeitet an echten Web-Anwendungen – nicht an Spielwiesen.
Dieser Karrierepfad führt dich gezielt von den Grundlagen über Architektur und Design bis hin zu professionellen React-Frontends, wie sie in produktiven Teams erwartet werden. Starte einfach durch!
Die Grundlagen
Einstieg in React
Wo du genau das übst
Ein sehr gutes, praxisorientiertes und nachhaltiges Seminar. So sollte es immer sein. Vielen Dank.
Die Schulung ist gerade für Einsteiger oder Entwickler*innen mit eingestaubtem Basiswissen sehr hilfreich.
Ich bin sehr glücklich Franz als Trainer gehabt zu haben. Er hat offensichtlich unglaublich viel Wissen zu den Themen, und schafft es, dieses auch interaktiv und verständlich weiterzugeben.
Häufige Fragen
Ist jeder überflüssige Durchlauf ein Problem?
Soll ich alle Komponenten in memo einpacken?
Warum läuft in der Entwicklung alles doppelt?
Lohnt sich der React Compiler in einem bestehenden Projekt?
Deine Ansprechpartner
Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.
Yves Hoppe
Weiterbildung & Beratung
Hilft dir, aus dem Webentwicklung-Programm den passenden Kurs für deinen Stand zu finden.
Norbert Jansen
Beratung & Inhouse
Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.
Leistungsfragen mit Messung statt mit Bauchgefühl
In den React-Angeboten von cmt zeichnest du eine träge Oberfläche selbst auf, liest den Auslöser im Profiler ab und siehst, welcher Eingriff wirklich etwas bringt.