DEV Community

Haochen
Haochen

Posted on

I Built a “Real‑Time Dashboard Mock” Because Interviews Wouldn’t Let It Go

Try it out here:

If you've ever been asked in an interview, "How would you handle real-time, high-frequency data on the frontend?" — welcome to my personal saga. I've heard that question so many times that I finally turned it into a project.
This repo is a Real-Time Dashboard Mock: a playful but practical sandbox that simulates polling/WebSocket-style data firehose and asks your UI to keep up. Think: tens of thousands of list rows, continuous updates, and user interactions (edit, filter, sort) happening at the same time.

Why I Built It

Because interviews don't just want theory — they want proof. This repo is my answer: a visible, testable environment to explore what "smooth" actually means under load.

What's Inside

• A mock data hose that floods the frontend at adjustable rates.
• A dashboard UI where you can filter, edit, and sort while data streams in.
• A clear separation between setup and business UI, so optimization work stays clean.

Where to Optimize

The optimization work lives in src/Dashboard.tsx. That's where you can dig into techniques like these:
• List virtualization — only render rows in the viewport. Libraries like react-window or TanStack Virtual make 50k rows feel trivial.
• Memoization — wrap row components in React.memo and stabilize callbacks with useCallback to stop cascade re-renders on every tick.
• Deferred filtering — use useDeferredValue or debounce to delay expensive filter recalculations while the stream keeps flowing.
• Batching — buffer incoming tick events and flush them in a single setState call per frame to cut re-render frequency way down.
• ID-to-index map — maintain a Map alongside your array so deletions and lookups are O(1) instead of scanning the entire list every time.
• Normalized state — store rows in a Map instead of an array. Updates and deletes become direct key lookups with no find(), splice(), or indexOf() needed.
• Separate display order — keep a dedicated ordered array of IDs for rendering. Sorting only reshuffles the ID list; the data map stays untouched.
• Web Worker offloading — push sort and filter logic off the main thread so the UI stays responsive during heavy computation.
• requestAnimationFrame throttling — gate state flushes to rAF so you never commit more than one update per paint cycle regardless of tick rate.
• Structural sharing — on each update, only create new objects for rows that actually changed so React.memo can bail out cheaply on untouched rows.
The stream generator and tuning controls live in src/App.tsx. That stays as the mock setup layer so your optimizations don't get tangled with the test harness.

Want the Original Unoptimized Challenge?

Check out the /problem branch. That's the raw version without any fixes — perfect if you want to feel the pain first and build your own strategy from scratch.

Try Breaking It

As the time of writing, I haven't fully optimize it yet, but you can test its limit by:
• Crank the tick interval way down.
• Increase batch size.
• Filter while data is flowing.
• Edit rows mid-stream.
• Sort at 100k+ rows.
• Delete items rapidly and watch how long the list scan takes.
If the UI stays smooth, you win. Drop a star on the repo if it helped, or open a PR if you find a technique worth adding.

GitHub logo hcsum / realtime-dashboard-mock

A dashboard demo to handle large volume and frequent data updates

Real‑time Dashboard Mock

This repo simulates a high‑frequency data hose (polling/WebSocket‑like) and a dashboard UI that must stay responsive while rendering a large list.

Quick start

pnpm install
pnpm dev
Enter fullscreen mode Exit fullscreen mode

Where to add your optimized code

Put your rendering and interaction optimizations in the Dashboard component:

  • src/Dashboard.tsx — list rendering, filtering, editing, and user interaction live here.
  • src/App.tsx — stream “hose” and tuning controls live here. Keep this as the mock setup layer.

If you want to compare against the original unoptimized version, check out the /problem branch.

What to try

  • Set Tick Interval to a very low value and Batch Size high to stress the UI.
  • Type in the filter while the stream is running.
  • Edit titles/notes while items are streaming in.
  • Sort the list while the stream is active with 5,000+ rows.

Notes / structure

  • Dashboard rendering is isolated in src/Dashboard.tsx so you can optimize without touching the…

Top comments (0)