Praktische Hinweise: Wie ich eine langsame React-App ohne Neuimplementierung optimiert habe
Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: Wie ich eine langsame React-App ohne Neuimplementierung optimiert habe – Verträge, Überprüfungen sowie Code-Slots für Teams, die dieses Muster einsetzen.
Nutzen Sie dies als für Operator zugängliche Neuformulierung der Ideen aus „How I Optimized a Slow React App Without Rewriting It“: klare Phasen, geordnete Codeabschnitte sowie Wiederherstellungshinweise, die auch bei Übergaben erhalten bleiben. Die Überblicksphase funktioniert am besten, wenn sie als messbarer Rahmen betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlerfall sowie die Notizen zur Rücksetzung. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.
Die Diagnose: Das Problem finden
Zur Bestimmung des Stadiums bei der Diagnose sollten vor dem Ändern des Codes die Eingabedaten, der Verantwortliche für den jeweiligen Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Ablauf von einer Demo-Umgebung in eine gemeinsam genutzte Umgebung wechselt. Der Zustand sollte zusammen mit dem Komponenten gespeichert werden, der für die Mutation verantwortlich ist. Das Hinzufügen aller Daten in einen globalen Speicher erschwert es, Timing-Probleme zu erkennen.
1. React.memo: Der einfachste Weg zum Erfolg
Für das 1 React-Memo „The Stage“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Operator:innen sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zustand schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Operator:innen überprüfen können, ohne den gesamten Graphen durchlesen zu müssen. Platzieren Sie den Zustand zusammen mit der Komponente, die für die Mutation verantwortlich ist. Das Hochladen aller Daten in einen globalen Speicher erschwert das Erkennen von Timing-Fehlern.
const ExpensiveComponent = React.memo(({ data, onUpdate }) => {
// Component logic
});
2. useMemo und useCallback: Beendigung rekursiver Neuberechnungen
Für die beiden Phasen von useMemo und useCallback sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zuständen schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlnachrichten gehören zum Produkt selbst, nicht zu späteren Optimierungen. Platzieren Sie den Zustand zusammen mit der Komponente, die die Mutation verantwortet. Das Hochladen aller Daten in einen globalen Speicher erschwert das Erkennen von Zeitproblemen. Für die beiden Phasen von useMemo und useCallback sollten vor dem Ändern des Codes die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zuständen schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.
const computedStats = useMemo(() => {
return expensiveAggregation(data);
}, [data]);
const handleUpdate = useCallback((id) => {
updateItem(id);
}, []);
3. useTransition: Priorisierung von Benutzerinteraktionen
Beim Arbeiten an der Phase „Priorisierung von Benutzerinteraktionen“ mit useTransition sollten Sie zunächst den Vertrag festhalten: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Notieren Sie die Laufzeiten sowie die Kosten für Tokens oder Abfragen neben den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo in gemeinsam genutzte Umgebungen wechselt. Betrachten Sie Effekte als Synchronisierung mit der Außenwelt und nicht als Ersatz für berechnete Werte während der Darstellung.
const [isPending, startTransition] = useTransition();
const handleSearch = (term) => {
startTransition(() => {
setSearchTerm(term);
// Filtering happens in the background
});
};
4. useDeferredValue: Glättung teurer Darstellungen
Beim Bearbeiten der Stufe „4 useDeferredValue Smoothing Out“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den Betreiber überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen. Betrachten Sie Effekte als Synchronisierung mit der Außenwelt und nicht als Ersatz für berechnete Werte während der Darstellung.
const deferredData = useDeferredValue(data);
// Chart receives deferredData and updates only when React has idle time
5. Virtualisierung: Nur das Sichtbare darstellen
Beim Arbeiten in der Phase „Nur Virtualisierung und Rendering“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Wiederherstellungsprozess gemeinsam. Wiederholte Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Betrachten Sie Auswirkungen als Synchronisierung mit der Außenwelt – nicht als Ersatz für berechnete Werte während des Renderings. Beim Arbeiten in der Phase „Nur Virtualisierung und Rendering“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab.
import { FixedSizeList } from 'react-window';
const Row = ({ index, style }) => (
<div style={style}>
{data[index].name}
</div>
);
<FixedSizeList
height={400}
itemCount={data.length}
itemSize={35}
width="100%"
>
{Row}
</FixedSizeList>
6. Träge Ladung: Code-Teilung nach Route
Die 6. Phase der tragen Ladung funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie ein optimales Ergebnis, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Erfassen Sie außerdem die Laufzeiten sowie die Kosten für Token oder Abfragen zusammen mit den funktionalen Ergebnissen. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn sich der Pfad von einer Demo-Umgebung in gemeinsam genutzte Umgebungen verschiebt. Halten Sie die Render-Arbeit kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann Fehler durch veraltete Eigenschaften verbergen.
const Dashboard = lazy(() => import('./views/Dashboard'));
const Analytics = lazy(() => import('./views/Analytics'));
function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/analytics" element={<Analytics />} />
</Routes>
</Suspense>
);
}
7. useMemoizedSelector: Optimierung der Zustandsverwaltung
Die 7 Stufen der State-Management-Methode useMemoizedSelector funktionieren am besten, wenn sie als messbarer Bereich betrachtet werden. Erfassen Sie einen idealen Ablauf, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort zusammengefasst sein, den Betreuer ohne das Durchlesen des gesamten Systems überprüfen können. Halten Sie die Render-Arbeit kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann Fehler durch veraltete Props verbergen.
import { createSelector } from '@reduxjs/toolkit';
const selectFilteredData = createSelector(
(state) => state.items,
(state) => state.filterTerm,
(items, term) => items.filter(item =>
item.name.toLowerCase().includes(term.toLowerCase())
)
);
// In component:
const filteredData = useSelector(selectFilteredData);
Die Zahlen: Vor und Nach
The The Numbers Before und die jeweilige Phase funktionieren am besten, wenn sie als messbare Einheit betrachtet werden. Erfassen Sie vor Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Dokumentieren Sie gleichzeitig den erfolgreichen Ablauf sowie den Wiederherstellungsprozess. Versuche, menschliche Kontrollen und die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie die Renderarbeiten kostengünstig und verschieben Sie aufwändige Berechnungen erst nach Messung hinter die Memoisierung – eine vorzeitige Memoisierung kann fehlerhafte Eigenschaften verbergen. The The Numbers Before und die jeweilige Phase funktionieren am besten, wenn sie als messbare Einheit betrachtet werden. Erfassen Sie vor Erweiterung des Umfangs ein „goldenes“ Transkript, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Ergebnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.
Die Denkweise ändern
Zur Phase „Mindset Shift“ sollten die Eingabedaten, der Verantwortliche für den Schritt sowie die Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Zeiten sowie Kosten für Token oder Abfragen sollten neben den funktionalen Ergebnissen aufgezeichnet werden. Eine frühzeitige Sichtbarkeit der Kosten verhindert überraschende Rechnungen, wenn der Weg von einer Demo-Umgebung in gemeinsam genutzte Umgebungen wechselt. Der Zustand sollte zusammen mit dem Komponenten gespeichert werden, der für die Mutation verantwortlich ist. Das Hinzufügen aller Daten in einen globalen Speicher erschwert es, Timing-Probleme zu erkennen.
Zusammenfassung
Für die Phase „The Bottom Line“ sollten Eingabedaten, Verantwortliche für die jeweiligen Schritte sowie Abbruchkriterien vor dem Ändern des Codes definiert werden. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Die Konfiguration sollte außerhalb des Anwendungscode gespeichert werden. Umgebungsdateien, Geheimdatenspeicher sowie Feature-Flags sollten an einem Ort zusammengefasst sein, den die Operator überprüfen können, ohne den gesamten Codeverlauf durchlesen zu müssen. Der Zustand sollte zusammen mit dem Komponenten gespeichert werden, der für die Mutation verantwortlich ist. Das Zusammenfassen aller Daten in einem globalen Speicher erschwert es, Zeitbezogene Fehler zu erkennen.
Operative Checkliste
Während der Bearbeitung der operativen Checkliste sollte zunächst der Vertrag festgehalten werden: erforderliche Eingabedaten, Signal für Erfolg sowie Folgen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben.
Man sollte kleine, testbare Einheiten vor umfangreichen Skripten bevorzugen. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufverfahren.
Betrachten Sie Effekte als Synchronisierung mit der Außenwelt, nicht als Ersatz für berechnete Werte während der Renderung.
Festlegen Sie die Versionen der Abhängigkeiten und speichern Sie den Bild-Digest, mit dem die Demo ausgeführt wurde. Reproduzierbarkeit ist besser als „stammesweises Wissen“.
Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Erzeugnisse, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab.
Betrachten Sie Effekte als Synchronisierung mit der Außenwelt, nicht als Ersatz für berechnete Werte während der Renderung.
Vor der Einführung des Stacks sollten Versionen eingefroren werden, ein „goldener“ Transkript für den kritischen Pfad erstellt und die Rollback-Schritte bestätigt werden. Gemeinsam genutzte Umgebungen benötigen Rate Limits, Überprüfungen der Nutzerzuordnung sowie einen klaren Verantwortlichen für die Rotation von Geheimnissen. Man sollte langweilige Zuverlässigkeit vor cleveren, einmaligen Demonstrationen bevorzugen.
Batch-Hinweis für d6a7f4e83dda: Halten Sie die Provider-Schlüssel außerhalb des Repositories, legen Sie eine Obergrenze für Tokens pro Sitzung fest und speichern Sie die Transkripte neben den Evaluierungs-Fixtures, damit spätere Modellwechsel vergleichbar bleiben.