Skip to content

junhyeong9812/perf-pilot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PerfPilot

Chrome extension for real-time frontend performance measurement. Provides a modal overlay and DevTools panel dashboard to help frontend developers monitor Web Vitals, network requests, DOM interactions, FPS, and memory usage.

Features

  • Web Vitals — TTFB, FCP, LCP, CLS, INP with threshold ratings (good/warning/bad) and descriptions
  • Customizable Thresholds — Adjust good/warn thresholds per metric via settings panel (gear icon). Persisted across sessions
  • Network Monitoring — Intercepts fetch, XHR, WebSocket, and SSE with timing and status
  • Interaction Tracking — Measures click/keydown/input to DOM mutation delay + per-interaction heap delta
  • FPS & Long Frames — requestAnimationFrame-based FPS counter + Long Animation Frame (LoAF) detection with script attribution
  • JS Heap Memory — Tracks usedJSHeapSize, totalJSHeapSize, and usage percentage in real-time
  • React Component Tracking — Auto-detects React, tracks per-component render counts, identifies re-render causes (prop/hook/parent), cascade mapping (trigger → affected components)
  • Network→Render Correlation — Links API responses to React commits within 500ms window
  • CSS Inspector — Click-to-inspect mode with element highlighting; shows matched CSS rules sorted by specificity, inline styles, !important flags, and inherited properties
  • DOM Tree View — Structure snapshot around the inspected element (ancestors + descendants) with element path generation
  • Dual View — Modal overlay (icon click) + DevTools panel (PerfPilot tab)
  • Cookie Storage — Persists measurement data and settings in cookies with perfpilot_ namespace

Architecture

[Extension Icon Click]              [Open DevTools]
       │                                  │
       ▼                                  ▼
  background.js                     devtools.js
  (Service Worker)                  → panel.html
       │                                  │
       ▼                                  │
  content.js (ISOLATED)                   │
  ├── Modal overlay (Shadow DOM)          │
  ├── Bridge (postMessage → runtime)──────┘
  └── Cookie storage
       │
  inject.js (MAIN world)
  ├── Web Vitals (PerformanceObserver)
  ├── Network (fetch/XHR/WS/SSE monkey-patch)
  ├── DOM Observer (MutationObserver)
  ├── FPS (rAF + LoAF)
  ├── Memory (performance.memory)
  └── CSS Inspector / DOM Tree (inspect mode)

Data Collection Pipeline

How a metric travels from the page to the dashboards:

  1. Injectioncontent.js (ISOLATED world, run_at: document_start) asks the service worker to inject inject.js into the MAIN world via chrome.scripting.executeScript. Collectors must live in the MAIN world to reach page-level objects: React fiber roots, performance.memory, and the page's own fetch/XMLHttpRequest to monkey-patch.

  2. Collectioninject.js wires up the collectors, each observing a different signal source:

Collector Source API Events emitted
web-vitals.js PerformanceObserver web-vital
network.js fetch/XHR/WebSocket/SSE monkey-patch network-request
dom-observer.js MutationObserver + click/keydown/input listeners interaction, dom-mutation
fps.js requestAnimationFrame loop + LoAF observer fps, long-frame
memory.js performance.memory polling (2s interval) memory
react-tracker.js __REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot (installs the hook, or wraps the existing one if React DevTools is present) react-detected, react-commit, react-stats
css-inspector.js + dom-tree.js getComputedStyle + stylesheet rule matching, DOM traversal inspect results
  1. MAIN → ISOLATED bridge — every event leaves the MAIN world as window.postMessage({ source: 'perf-pilot', type, payload }). bridge.js in the ISOLATED world filters by source and event.source === window, then dispatches to type-based listeners registered by content.js.

  2. Fan-outcontent.js consumes each event twice: it updates the modal dashboard (Shadow DOM) directly, and forwards the same message via chrome.runtime.sendMessage to the service worker.

  3. Routing to DevToolsbackground.js keeps a tabId → port map of connected DevTools panels (devtools-panel ports). Incoming messages are routed to the panel of the originating tab only, so multiple tabs can be measured independently.

  4. Persistencestorage.js saves measurement data and settings as cookies under the perfpilot_ namespace (≤3800 bytes per key; older entries are trimmed when over the limit), so data survives reloads without any external server. Nothing leaves the browser — there is no remote collection endpoint.

Setup

npm install
npm run build

Load in Chrome

  1. Open chrome://extensions
  2. Enable Developer mode
  3. Click Load unpacked → select the dist/ folder
  4. Visit any website → click the PerfPilot icon for the modal overlay
  5. Open DevTools → navigate to the PerfPilot tab

Development

npm run dev    # watch mode (rebuilds on file changes)
npm run build  # production build

Project Structure

src/
├── manifest.json                    # Chrome MV3 manifest
├── background.js                    # Service worker (icon click + port routing)
├── icons/                           # Extension icons (16, 48, 128px)
├── inject/
│   ├── inject.js                    # MAIN world entry (aggregates collectors)
│   └── collectors/
│       ├── web-vitals.js            # TTFB, FCP, LCP, CLS, INP
│       ├── network.js               # fetch/XHR/WebSocket/SSE intercept
│       ├── dom-observer.js          # MutationObserver + interaction timing
│       ├── react-tracker.js         # React hook setup + commit tracking
│       ├── fiber-utils.js           # Fiber tree traversal + render cause analysis
│       ├── fps.js                   # rAF FPS + LoAF
│       ├── memory.js                # JS heap memory tracking
│       ├── css-inspector.js         # Inspect mode + rule matching, specificity, inheritance
│       └── dom-tree.js              # DOM structure snapshot + element path
├── content/
│   ├── content.js                   # ISOLATED world entry + modal dashboard
│   ├── bridge.js                    # MAIN ↔ ISOLATED message bridge
│   └── storage.js                   # Cookie-based data persistence
└── devtools/
    ├── devtools.html                # DevTools entry page
    ├── devtools.js                  # Panel creation
    ├── panel.html                   # Panel HTML
    ├── panel.css                    # Panel styles
    └── panel.js                     # Port connection + dashboard rendering

Tech Stack

  • Vanilla JS — No framework, minimal bundle size
  • Vite — Build tool with multi-entry rollup config
  • Chrome Extension MV3 — Manifest V3, service worker, content scripts
  • Shadow DOM — Modal overlay isolated from page CSS

Browser Compatibility

  • Chrome 123+ (for Long Animation Frame API)
  • Chrome 116+ (for all other features)
  • performance.memory is Chrome-specific (memory section gracefully hidden in other browsers)

Roadmap

  • Phase 1 — Universal performance metrics (Web Vitals, Network, FPS, Memory)
  • Phase 2 — React component render tracking via fiber tree
  • Phase 3 — CSS debugging + DOM element structure analysis

About

Web Vitals·네트워크·FPS·메모리·React 리렌더·CSS 검사를 실시간 측정하는 크롬 익스텐션 성능 대시보드 (Chrome MV3, Vanilla JS)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors