Optimizing Real-Time Dashboards: How We Achieved a 40% Performance Boost
Building a dashboard that looks good is easy. Building one that handles 10,000+ updates per second without freezing the main thread is a different beast entirely. Here's how we optimized our high-frequency trading dashboard to achieve sub-16ms frame times.
The Bottleneck: Main Thread Blocking
Our initial implementation used a standard React `useEffect` to subscribe to WebSocket updates. As the volume of data increased, the UI became unresponsive. The browser's main thread was choked by JSON parsing and React reconciliation, leading to dropped frames and a janky user experience.
Solution 1: Offloading to Web Workers
To unblock the main thread, we moved the WebSocket connection and data processing logic to a Web Worker. This allowed us to parse incoming JSON and perform heavy calculations (like moving averages) in a background thread, sending only the final, render-ready data back to the main thread.
// worker.js
self.onmessage = (e) => {
const { type, payload } = e.data;
if (type === 'CONNECT') {
const socket = new WebSocket(payload.url);
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
const processed = calculateMetrics(data);
self.postMessage({ type: 'UPDATE', payload: processed });
;
}
};Solution 2: Throttling React Updates
Even with Web Workers, pushing 100 updates per second to React state triggers too many re-renders. We implemented a requestAnimationFrame loop to batch updates, ensuring the UI only re-renders in sync with the browser's refresh rate (typically 60fps).
The Result: Silky Smooth 60fps
By combining Web Workers for data processing and `requestAnimationFrame` for rendering control, we reduced the main thread load by 40%. The dashboard now handles high-frequency data bursts without dropping a single frame, providing traders with the real-time precision they need.