Skip to main content
Case StudiesProjectsAbout
Case StudiesProjectsAbout
Project

Performance Monitor

Real-time bundle analyzer and runtime performance tracker for React apps.

3 min read
ViteesbuildWebSockets
<1%
Observer overhead
at 10% sampling rate
Real-time
HMR latency
bundle data on every update
Baseline diff
CI mode
non-zero exit on threshold breach
My Role
Solo: design, engineering
Timeline
2024
Team
1 engineer
Platform
Web
Stack
Vite · esbuild · React · Node.js · WebSockets · Performance Observer API
Status
Shipped

Overview

A development tool that provides real-time insights into React application performance, combining bundle analysis with runtime metrics. Shows component render times, bundle composition, and identifies performance bottlenecks as you develop, without switching to the browser DevTools.

Architecture

Bundle analysis (Vite plugin) Hooks into esbuild's build pipeline via the generateBundle hook. Reads esbuild's metafile (enabled via metafile: true) to get input/output size relationships. Streams this data to a WebSocket server on build completion and on HMR updates.

Runtime monitoring (React component) A <PerformanceMonitor> wrapper uses React Profiler API to collect render timing. Performance Observer API captures LCP, CLS, INP, and resource timing. All data flows to a local dashboard at localhost:4000.

Key Features

vite-plugin-usage.ts
// vite.config.ts
import { performanceMonitor } from '@yourname/perf-monitor/vite';

export default defineConfig({
  plugins: [
    performanceMonitor({
      port: 4000,
      threshold: {
        bundleSize: 500 * 1024, // alert if bundle > 500KB
        renderTime: 16,          // alert if render > 16ms (1 frame)
      },
    }),
  ],
});
// Wrap your app root
<PerformanceMonitor enabled={process.env.NODE_ENV === 'development'}>
  <App />
</PerformanceMonitor>
●Sampling to Minimize Overhead

The monitor uses a 10% sampling rate by default for React Profiler data. At 100% sampling, the observer itself becomes a measurable overhead. Sampling gives statistically accurate data with minimal impact on actual render performance. The dashboard aggregates across samples to show accurate percentiles.

WebSocket Reconnection

websocket-client.ts

The WebSocket client uses exponential backoff with state reconciliation on reconnect:

// On reconnect, request a full state snapshot from the server
// rather than replaying missed events, avoids state drift
ws.addEventListener('open', () => {
  if (wasDisconnected) {
    ws.send(JSON.stringify({ type: 'REQUEST_SNAPSHOT' }));
  }
});

This handles the common case where the dev server restarts (Vite HMR cache clear) and the client reconnects mid-session without losing the session's accumulated metrics.

CI Integration

The plugin can run in CI mode: no WebSocket server, outputs a JSON report instead. Configured via PERF_MONITOR_CI=true. CI mode compares the current build against a baseline stored in .perf-baseline.json and exits non-zero if any threshold is exceeded.

Tech Stack

Vite · esbuild · React · Performance Observer API · React Profiler API · WebSockets · Node.js

PreviousDesign System Foundation
NextPromptopia

Built with intention, not templates. If you made it this far, thank you for reading thoughtfully.

© 2026 · Designed and built with care