A security dashboard is a stress test disguised as a UI. Ten thousand rows, sub-second updates, filters, selection, and a live feed — all at once. Naive React melts here, and the fix is architectural, not a sprinkle of memoization.
Virtualize first
You never render 10,000 rows. You render the ~40 in the viewport and recycle nodes as the user scrolls. Everything else is bookkeeping.
// Presentational, pure, windowed. Data lives in a cache hook.
function AlertTable({ rows }) {
const v = useVirtual({ count: rows.length, estimateSize: () => 44 });
return v.items.map(i => <AlertRow key={rows[i].id} row={rows[i]} />);
}Tame the updates
- Batch real-time events and flush on a frame, so a burst of 300 alerts is one render, not 300.
- Keep server state in a cache with stable references; only the rows that changed re-render.
- Profile before memoizing — add React.memo where the flamegraph says so, not by vibes.
Performance is a feature in a SOC tool. A dashboard that stutters during an incident is a dashboard nobody trusts.
Done right, the interface stays fluid at volumes that would lock a generated prototype on the first real day of traffic.
