Skip to main content

Performance Monitoring

Using devtool-mcp to analyze, diagnose, and improve web application performance.

Overview

devtool-mcp provides multiple tools for performance analysis:

  • Proxy traffic logs - Request/response timing
  • Performance metrics - Page load, paint timing
  • Network capture - Resource loading analysis
  • Process monitoring - Build and runtime performance

Setting Up Performance Monitoring

Start with Proxy

// Start your app
run {script_name: "dev"}

// Create proxy for monitoring
proxy {action: "start", id: "perf", target_url: "http://localhost:3000", port: 8080}

Browse through http://localhost:8080 to capture metrics.

Analyzing Page Load Performance

Get Performance Metrics

proxylog {proxy_id: "perf", types: ["performance"]}
{
entries: [{
url: "http://localhost:8080/dashboard",
navigation: {
dom_content_loaded: 1250, // DOM ready
load_event: 2800 // Fully loaded
},
paint: {
first_paint: 450, // First pixels
first_contentful_paint: 680 // First content
},
resources: [...]
}]
}

Interpret Results

MetricGoodNeeds WorkPoor
First Paint< 1s1-2s> 2s
First Contentful Paint< 1.5s1.5-2.5s> 2.5s
DOM Content Loaded< 2s2-4s> 4s
Load Event< 3s3-5s> 5s

Analyzing Network Performance

Capture Network Data

proxy {action: "exec", id: "perf", code: "window.__devtool.captureNetwork()"}
{
summary: {
totalResources: 42,
totalTransferSize: 2500000,
totalDuration: 3200,
byType: {
script: {count: 8, size: 1800000},
stylesheet: {count: 3, size: 150000},
image: {count: 25, size: 450000},
fetch: {count: 6, size: 100000}
}
},
entries: [...]
}

Find Slow Resources

// Get all resources sorted by duration
proxy {action: "exec", id: "perf", code: `
const network = window.__devtool.captureNetwork();
const slow = network.entries
.filter(e => e.duration > 500)
.sort((a, b) => b.duration - a.duration)
.slice(0, 10);
slow
`}
→ Top 10 slowest resources

Find Large Resources

proxy {action: "exec", id: "perf", code: `
const network = window.__devtool.captureNetwork();
const large = network.entries
.filter(e => e.transferSize > 100000)
.sort((a, b) => b.transferSize - a.transferSize);
large.map(e => ({name: e.name, size: Math.round(e.transferSize/1024) + 'KB'}))
`}
→ Large resources with sizes

API Performance Analysis

Track API Response Times

proxylog {proxy_id: "perf", types: ["http"], url_pattern: "/api"}
{
entries: [
{url: "/api/users", duration_ms: 45},
{url: "/api/products", duration_ms: 1200}, // Slow!
{url: "/api/cart", duration_ms: 89}
]
}

Find Slow Endpoints

// Filter for slow API calls (>500ms)
proxylog {proxy_id: "perf", types: ["http"], url_pattern: "/api"}
// Then filter results for duration_ms > 500

Analyze Request Patterns

proxylog {proxy_id: "perf", action: "stats"}
{
by_type: {http: 150},
// Look at request volume
}

Build Performance

Monitor Build Times

// Time your build
run {script_name: "build", mode: "foreground"}
{runtime: "45.2s"}

// Check for issues
proc {action: "output", process_id: "build", grep: "(warning|slow|large)"}

Analyze Bundle Size

// Run build analysis
run {raw: true, command: "npx", args: ["source-map-explorer", "dist/main.js"], mode: "foreground-raw"}

// Or with bundle analyzer
run {script_name: "build:analyze", mode: "foreground"}

Real-Time Monitoring

Page Session Analysis

// See all loaded pages
currentpage {proxy_id: "perf"}
{
sessions: [
{url: "/dashboard", resource_count: 35, error_count: 0},
{url: "/products", resource_count: 42, error_count: 2}
]
}

// Get details for slow page
currentpage {proxy_id: "perf", action: "get", session_id: "page-1"}
→ Full breakdown of resources and timing

Live Traffic Analysis

// Recent traffic with timing
proxylog {proxy_id: "perf", types: ["http"], since: "1m", limit: 50}

Performance Optimization Workflow

Step 1: Baseline Measurement

// Navigate to page
// Get current performance
proxylog {proxy_id: "perf", types: ["performance"]}
{navigation: {load_event: 4500}} // 4.5s - too slow

proxy {action: "exec", id: "perf", code: "window.__devtool.captureNetwork()"}
{summary: {totalTransferSize: 3500000}} // 3.5MB

Step 2: Identify Bottlenecks

// Find blocking resources
proxy {action: "exec", id: "perf", code: `
const network = window.__devtool.captureNetwork();
network.entries
.filter(e => e.renderBlockingStatus === 'blocking' || e.type === 'script')
.sort((a, b) => b.duration - a.duration)
`}

// Find large JS bundles
proxy {action: "exec", id: "perf", code: `
const network = window.__devtool.captureNetwork();
network.entries
.filter(e => e.type === 'script' && e.transferSize > 50000)
`}

Step 3: Make Improvements

Based on findings:

  • Add code splitting for large bundles
  • Lazy load below-fold images
  • Add caching headers
  • Compress assets

Step 4: Verify Improvement

// After changes, measure again
proxylog {proxy_id: "perf", types: ["performance"]}
{navigation: {load_event: 2100}} // 2.1s - improved!

proxy {action: "exec", id: "perf", code: "window.__devtool.captureNetwork()"}
{summary: {totalTransferSize: 1200000}} // 1.2MB - improved!

Core Web Vitals

Collect Web Vitals

proxy {action: "exec", id: "perf", code: `
const perf = window.__devtool.captureNetwork();
const paint = performance.getEntriesByType('paint');
const nav = performance.getEntriesByType('navigation')[0];

({
LCP: paint.find(p => p.name === 'largest-contentful-paint')?.startTime,
FCP: paint.find(p => p.name === 'first-contentful-paint')?.startTime,
TTFB: nav?.responseStart,
// CLS and FID require PerformanceObserver
})
`}

Targets

MetricGoodNeeds ImprovementPoor
LCP< 2.5s2.5-4s> 4s
FID< 100ms100-300ms> 300ms
CLS< 0.10.1-0.25> 0.25
TTFB< 800ms800-1800ms> 1800ms

Layout Performance

Find Layout Thrashing

proxy {action: "exec", id: "perf", code: "window.__devtool.diagnoseLayout()"}
{
overflows: [...],
summary: {overflowCount: 3}
}

Check for Forced Reflow

// This is a code inspection rather than runtime check
// Look for patterns that cause layout thrashing
proxy {action: "exec", id: "perf", code: `
// Check for large DOM trees
document.querySelectorAll('*').length
`}

Monitoring Dashboard Example

// Create a simple performance dashboard
proxy {action: "exec", id: "perf", code: `
const metrics = {};

// Page load
const perf = proxylog({types: ['performance']});
metrics.pageLoad = perf.entries[0]?.navigation?.load_event;

// Resource count
const network = window.__devtool.captureNetwork();
metrics.resourceCount = network.summary.totalResources;
metrics.totalSize = Math.round(network.summary.totalTransferSize / 1024) + 'KB';

// Error count
const errors = proxylog({types: ['error']});
metrics.errorCount = errors.entries.length;

metrics
`}

Best Practices

  1. Always baseline first - Measure before optimizing
  2. Focus on user-centric metrics - LCP, FID, CLS
  3. Check both fast and slow connections - Use browser throttling
  4. Monitor over time - Performance can regress
  5. Test real pages - Home page often differs from inner pages
  6. Check mobile - Often slower than desktop

Common Performance Issues

IssueDetectionSolution
Large JS bundlescaptureNetwork() by typeCode splitting
Render-blocking CSSCheck resource timingInline critical CSS
Slow API callsproxylog by URL patternCaching, optimization
Too many requestscaptureNetwork() countBundling, sprites
Large imagescaptureNetwork() by sizeCompression, lazy load

See Also