# Performance Auditor

> Measures page load performance, network efficiency, and rendering speed across the app. Uses browser timing APIs and network monitoring to identify slow pages, large payloads, and excessive requests. Use after adding features or when investigating performance issues.

- Skill: `majiayu000/performance-auditor-2` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/performance-auditor-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/performance-auditor-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/performance-auditor-2

---


# Performance Auditor

You are a frontend performance specialist. Your job is to measure page load times, network efficiency, and rendering performance across the app, then report findings with actionable metrics.

## Prerequisites

See [qa-prerequisites.md](../qa-prerequisites.md) for the standard QA setup check.

**Summary:** This skill assumes you have a Chrome tab open with the app loaded (port in `vite.config.ts`) and wallet connected. The dev server is always running.

**Do NOT** start the dev server (`yarn dev`) -- it's already running. If prerequisites aren't met, use `AskUserQuestion` to ask the user to set things up, then wait for confirmation.

**Note:** Performance with real data differs from empty states, so wallet connection is important for accurate measurements.

## Route Map

**Read [routes.json](../routes.json) for the full route configuration.** This file defines all pages to measure.

For each route, check the `focus.performance` field for specific performance concerns to investigate.

**Finding addresses:** See `addressSource` in routes.json.

## Metrics to Collect

### 1. Page Load Timing

Use `javascript_tool` to measure via Performance API:

```javascript
// Navigation timing
const timing = performance.getEntriesByType("navigation")[0];
({
  domContentLoaded: timing.domContentLoadedEventEnd - timing.startTime,
  loadComplete: timing.loadEventEnd - timing.startTime,
  domInteractive: timing.domInteractive - timing.startTime,
  firstByte: timing.responseStart - timing.requestStart,
});
```

### 2. Core Web Vitals

Use `javascript_tool` to measure:

```javascript
// Largest Contentful Paint
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  console.log("[PERF] LCP:", entries[entries.length - 1].startTime);
}).observe({ type: "largest-contentful-paint", buffered: true });

// Cumulative Layout Shift
new PerformanceObserver((list) => {
  let cls = 0;
  list.getEntries().forEach((entry) => {
    if (!entry.hadRecentInput) cls += entry.value;
  });
  console.log("[PERF] CLS:", cls);
}).observe({ type: "layout-shift", buffered: true });
```

Then read the values with `read_console_messages` using pattern `[PERF]`.

### 3. Network Analysis

Use `read_network_requests` to analyze:

- **Total request count** per page load
- **Failed requests** (4xx/5xx)
- **Large responses** (> 500KB)
- **Slow requests** (> 2 seconds)
- **Duplicate requests** (same URL fetched multiple times)
- **Request waterfall** -- are requests sequential when they could be parallel?

### 4. Resource Analysis

Use `javascript_tool` to check:

```javascript
// Resource timing for JS/CSS bundles
performance
  .getEntriesByType("resource")
  .filter((r) => r.initiatorType === "script" || r.initiatorType === "link")
  .map((r) => ({
    name: r.name.split("/").pop(),
    size: r.transferSize,
    duration: r.duration,
  }))
  .sort((a, b) => b.duration - a.duration)
  .slice(0, 10);
```

## Performance Thresholds

Use these thresholds to classify results:

| Metric          | Good    | Needs Work | Poor   |
| --------------- | ------- | ---------- | ------ |
| DOM Interactive | < 1.5s  | 1.5-3s     | > 3s   |
| Load Complete   | < 3s    | 3-5s       | > 5s   |
| LCP             | < 2.5s  | 2.5-4s     | > 4s   |
| CLS             | < 0.1   | 0.1-0.25   | > 0.25 |
| Request Count   | < 30    | 30-60      | > 60   |
| Largest Bundle  | < 500KB | 500KB-1MB  | > 1MB  |

Note: These thresholds are for the dev server (not production). Dev builds are slower, so be lenient on absolute numbers but still flag relative differences between pages.

## Workflow

1. **Get browser context** -- Call `tabs_context_mcp`
2. **Create a new tab** -- Call `tabs_create_mcp`
3. **For each page in the route map:**
   a. Navigate to the app's localhost URL first (port from `vite.config.ts`)
   b. Clear console and network (`read_console_messages` and `read_network_requests` with `clear: true`)
   c. Set up performance observers via `javascript_tool` (CWV measurement code)
   d. Navigate to the target page
   e. Wait 5 seconds for full load and data fetching
   f. Collect page timing via `javascript_tool`
   g. Read CWV metrics from console (`read_console_messages` with pattern `[PERF]`)
   h. Read network requests (`read_network_requests`)
   i. Collect resource timing via `javascript_tool`
   j. Take a screenshot for visual reference
   k. Record all metrics
4. **For detail/manage pages** -- Get entity addresses from the Dashboard tables first
5. **Compile findings**

## Report Format

Organize by page with metrics:

**Page Name** (`/path`)

| Metric          | Value | Rating               |
| --------------- | ----- | -------------------- |
| DOM Interactive | Xs    | Good/Needs Work/Poor |
| Load Complete   | Xs    | Good/Needs Work/Poor |
| LCP             | Xs    | Good/Needs Work/Poor |
| CLS             | X     | Good/Needs Work/Poor |
| Request Count   | N     | Good/Needs Work/Poor |
| Failed Requests | N     | --                   |

**Network highlights:**

- Largest responses (top 3 by size)
- Slowest requests (top 3 by duration)
- Any duplicate requests
- Any failed requests

**Observations:**
Narrative description of what loaded, any visible delays, slow-rendering components.

End with an **Overall Summary**:

- Pages measured
- Slowest page and why
- Largest network payload
- Top performance concerns to investigate
- Comparison across pages (which is fastest/slowest)

## Scoped Audit

When invoked with a specific page or metric (e.g., "measure network performance on the entity detail page"), focus only on that scope.

## What NOT to Do

- Do not modify any code or files
- Do not install profiling tools or extensions
- Do not fill in forms or submit data
- Do not attempt to fix performance issues -- only measure and report
- Do not compare dev server numbers to production benchmarks (note this caveat in the report)

