Skip to content

A React 19 performance case study: Analyzing and resolving render waterfalls using React.memo, useCallback, and useMemo in a high-frequency data environment.

Notifications You must be signed in to change notification settings

furkanyasinengin/react-dashboard

Repository files navigation

Server Dashboard - React Performance Case Study

Server Dashboard is a real-time, high-frequency server monitoring dashboard.

While it functions as a UI dashboard, its primary purpose is to serve as a sandbox for demonstrating, analyzing, and solving React rendering performance issues. The project simulates a high-stress environment where data updates every second, intentionally causing "render waterfalls" to practice advanced optimization techniques.

🎯 Project Goal

The goal goes beyond "making it work." It aims to answer:

  • "Why is the Header re-rendering even though its props didn't change?"
  • "Why does passing a function to a child break React.memo?"
  • "When should I actually use useMemo?"

⚡ Optimization Journey

This project was built in two stages: Naive Implementation (unoptimized) and Refactored Implementation (optimized).

1. Stopping the "Render Waterfall" (React.memo)

  • Problem: Every time the server data updated in App.tsx, purely presentational components like <Header /> were re-rendering, even though their props (user="User") remained static.
  • Solution: Wrapped static components with React.memo to perform a shallow comparison of props before rendering.

2. The "Stale Reference" Trap (useCallback)

  • Problem: Even after applying React.memo to <ServerCard />, the cards kept re-rendering unnecessarily.
  • Root Cause: The onShutdown function passed from the parent was being recreated on every render (Referential Equality issue). To React, oldFunc !== newFunc, so it forced a re-render.
  • Solution: Wrapped the handler in useCallback to freeze the function reference across renders.

3. Expensive Calculations (useMemo)

  • Problem: The <Statistics /> component was recalculating active/offline counts and average CPU load on every single frame, regardless of whether the data was relevant to the calculation.
  • Solution: Utilized useMemo to cache the derived statistics. The calculation now only runs when the servers dependency specifically changes, ignoring other state updates (like UI theme toggles).

4. Derived State Pattern

  • Problem: Manually syncing a filteredServers state with the main servers state caused synchronization bugs and redundant renders.
  • Solution: Removed the redundant state. Implemented Derived State, calculating the filtered list on-the-fly during the render pass, ensuring a Single Source of Truth.

🛠 Tech Stack & Concepts

  • Core: React 19, TypeScript, Vite
  • Styling: Tailwind CSS
  • Architecture: Component Composition, Custom Hooks
  • Performance Hooks: useMemo, useCallback, React.memo
  • Visual Debugging: Custom useRenderHighlight hook (used during dev to visualize repaint zones).

📂 Project Structure

src/
├── components/
│   ├── Header.tsx        # Memoized static UI
│   ├── ServerCard.tsx    # Complex props & interaction handling
│   ├── ServerList.tsx    # List mapping abstraction
│   └── Statistics.tsx    # Heavy calculation component
├── hooks/
│   └── useRenderHighlight.ts # Custom visual profiler tool
├── utils/
│   └── dataGenerator.ts  # Simulates real-time network traffic
└── App.tsx               # Logic Controller & State Management

This project is designed for educational purposes to demonstrate the practical application of React performance hooks.

About

A React 19 performance case study: Analyzing and resolving render waterfalls using React.memo, useCallback, and useMemo in a high-frequency data environment.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published