home / skills / wesleysmits / agent-skills / performance-profiler

performance-profiler skill

/.agent/skills/performance-profiler

This skill runs performance audits with Lighthouse and Web Vitals, analyzes results, and delivers actionable optimizations to speed up pages.

npx playbooks add skill wesleysmits/agent-skills --skill performance-profiler

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
7.5 KB
---
name: profiling-performance
description: Runs performance audits and suggests optimizations using Lighthouse and Web Vitals. Use when the user asks about performance, page speed, Core Web Vitals, Lighthouse scores, or wants to optimize rendering and execution.
---

# Performance Profiler Assistant

## When to use this skill

- User asks to run a performance audit
- User mentions Lighthouse or Web Vitals
- User wants to improve page load speed
- User asks about LCP, FID, CLS, or INP
- User wants to profile CPU or memory usage
- User asks to optimize rendering performance

## Workflow

- [ ] Identify target URL or build to audit
- [ ] Run Lighthouse audit
- [ ] Collect Core Web Vitals metrics
- [ ] Analyze bundle size
- [ ] Profile runtime performance if needed
- [ ] Generate optimization recommendations
- [ ] Prioritize fixes by impact

## Instructions

### Step 1: Identify Audit Target

For deployed site:

```bash
# URL to audit
TARGET_URL="https://example.com"
```

For local development:

```bash
# Ensure dev server is running
npm run dev
TARGET_URL="http://localhost:3000"
```

For static build analysis:

```bash
npm run build
npx serve dist  # or out, build folder
```

### Step 2: Run Lighthouse Audit

**CLI audit:**

```bash
npx lighthouse $TARGET_URL --output=json --output=html --output-path=./lighthouse-report
```

**With specific categories:**

```bash
npx lighthouse $TARGET_URL --only-categories=performance,accessibility,best-practices,seo --output=json
```

**Mobile emulation (default):**

```bash
npx lighthouse $TARGET_URL --preset=desktop  # For desktop metrics
```

**Programmatic in Node.js:**

```javascript
import lighthouse from "lighthouse";
import * as chromeLauncher from "chrome-launcher";

const chrome = await chromeLauncher.launch({ chromeFlags: ["--headless"] });
const result = await lighthouse(url, { port: chrome.port });
console.log(result.lhr.categories.performance.score * 100);
await chrome.kill();
```

### Step 3: Interpret Core Web Vitals

| Metric                          | Good   | Needs Improvement | Poor   |
| ------------------------------- | ------ | ----------------- | ------ |
| LCP (Largest Contentful Paint)  | ≤2.5s  | 2.5s–4s           | >4s    |
| INP (Interaction to Next Paint) | ≤200ms | 200ms–500ms       | >500ms |
| CLS (Cumulative Layout Shift)   | ≤0.1   | 0.1–0.25          | >0.25  |
| FCP (First Contentful Paint)    | ≤1.8s  | 1.8s–3s           | >3s    |
| TTFB (Time to First Byte)       | ≤800ms | 800ms–1.8s        | >1.8s  |

### Step 4: Analyze Bundle Size

**Next.js:**

```bash
ANALYZE=true npm run build
# Or add to next.config.js:
# const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true' });
```

**Vite/Nuxt:**

```bash
npx vite-bundle-visualizer
# Or
npx nuxi analyze
```

**Generic webpack:**

```bash
npx webpack-bundle-analyzer stats.json
```

**Source map explorer:**

```bash
npx source-map-explorer dist/**/*.js
```

### Step 5: Profile Runtime Performance

**Chrome DevTools Performance tab:**

1. Open DevTools → Performance
2. Click Record
3. Perform user actions
4. Stop recording
5. Analyze flame chart for long tasks

**Measure in code:**

```typescript
// Performance marks
performance.mark("start-operation");
await heavyOperation();
performance.mark("end-operation");
performance.measure("operation", "start-operation", "end-operation");

const measures = performance.getEntriesByName("operation");
console.log(`Operation took ${measures[0].duration}ms`);
```

**React Profiler:**

```tsx
import { Profiler } from "react";

<Profiler
  id="Component"
  onRender={(id, phase, actualDuration) => {
    console.log(`${id} ${phase} render: ${actualDuration}ms`);
  }}
>
  <Component />
</Profiler>;
```

### Step 6: Generate Recommendations

**Report template:**

```markdown
## Performance Audit Report

**URL**: https://example.com
**Date**: 2026-01-18
**Device**: Mobile (Moto G Power)

### Scores

| Category       | Score |
| -------------- | ----- |
| Performance    | 72    |
| Accessibility  | 95    |
| Best Practices | 92    |
| SEO            | 100   |

### Core Web Vitals

| Metric | Value | Status               |
| ------ | ----- | -------------------- |
| LCP    | 3.2s  | ⚠️ Needs Improvement |
| INP    | 150ms | ✅ Good              |
| CLS    | 0.05  | ✅ Good              |

### Top Issues

#### 1. Large Contentful Paint (3.2s)

**Impact**: High
**Cause**: Hero image not optimized
**Fix**:

- Add `priority` to Next.js Image
- Use responsive srcset
- Preload LCP image

#### 2. Render-blocking resources

**Impact**: Medium
**Cause**: 3 CSS files blocking render
**Fix**:

- Inline critical CSS
- Defer non-critical styles
- Use `media` attribute for print styles

#### 3. Unused JavaScript (245KB)

**Impact**: Medium
**Cause**: Large vendor bundle
**Fix**:

- Enable tree shaking
- Dynamic import heavy components
- Remove unused dependencies
```

## Common Optimizations

### Images

```tsx
// Next.js - Use Image component with priority for LCP
import Image from "next/image";

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority // Preloads LCP image
  sizes="(max-width: 768px) 100vw, 1200px"
/>;
```

### Code Splitting

```tsx
// React - Lazy load heavy components
import { lazy, Suspense } from "react";

const HeavyChart = lazy(() => import("./HeavyChart"));

<Suspense fallback={<Loading />}>
  <HeavyChart />
</Suspense>;
```

```typescript
// Dynamic import for conditional features
const module = await import("./heavy-module");
```

### Font Optimization

```tsx
// Next.js - Use next/font
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"], display: "swap" });
```

```css
/* Self-hosted with font-display */
@font-face {
  font-family: "Custom";
  src: url("/fonts/custom.woff2") format("woff2");
  font-display: swap;
}
```

### Preloading Critical Resources

```html
<!-- Preload LCP image -->
<link rel="preload" as="image" href="/hero.webp" />

<!-- Preconnect to CDN -->
<link rel="preconnect" href="https://cdn.example.com" />

<!-- DNS prefetch for third parties -->
<link rel="dns-prefetch" href="https://analytics.example.com" />
```

### Reducing Layout Shift

```css
/* Reserve space for images */
img {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}

/* Reserve space for ads/embeds */
.ad-slot {
  min-height: 250px;
}
```

```tsx
// Always provide width/height
<Image width={800} height={450} ... />
```

### Caching

```javascript
// next.config.js - Cache static assets
module.exports = {
  async headers() {
    return [
      {
        source: "/_next/static/:path*",
        headers: [
          {
            key: "Cache-Control",
            value: "public, max-age=31536000, immutable",
          },
        ],
      },
    ];
  },
};
```

## Validation

Before completing:

- [ ] Lighthouse performance score ≥90
- [ ] All Core Web Vitals in "Good" range
- [ ] No render-blocking resources
- [ ] Bundle size within budget
- [ ] No layout shifts from loading content

## Error Handling

- **Lighthouse fails to run**: Ensure Chrome is installed and no conflicting flags.
- **Metrics vary wildly**: Run multiple times and average; use `--throttling.cpuSlowdownMultiplier`.
- **Can't reproduce field data**: Lab data differs from real users; use CrUX for field data.
- **Build analysis fails**: Ensure source maps are generated (`devtool: 'source-map'`).

## Resources

- [web.dev Performance](https://web.dev/performance/)
- [Lighthouse Documentation](https://developer.chrome.com/docs/lighthouse/)
- [Core Web Vitals](https://web.dev/vitals/)
- [Chrome UX Report](https://developer.chrome.com/docs/crux/)

Overview

This skill runs automated performance audits and delivers prioritized optimizations using Lighthouse and Core Web Vitals. It inspects lab metrics (Lighthouse scores), field metrics (CWV), bundle size, and runtime traces to find high-impact fixes. The output is a concrete, prioritized action list you can apply to improve load, interactivity, and layout stability.

How this skill works

Provide a target URL, local dev server, or build output. The skill runs Lighthouse (CLI or programmatic), collects Core Web Vitals, analyzes bundles with bundle analyzers, and profiles runtime via DevTools or code instrumentation. It synthesizes findings into a report with severity, root cause, and specific code or configuration changes to prioritize.

When to use it

  • You need a performance audit for a deployed site or local build
  • You want Lighthouse scores or Core Web Vitals analyzed (LCP, INP, CLS, FCP, TTFB)
  • You need bundle size or unused-JS analysis
  • You want actionable fixes for render-blocking resources or layout shifts
  • You want runtime profiling for long tasks and slow rendering

Best practices

  • Test both lab and field data: run Lighthouse and compare to CrUX or real-user metrics
  • Run audits multiple times and average results to reduce noise
  • Prioritize fixes by user-visible impact (LCP, INP, CLS) and cost to implement
  • Use code-splitting and dynamic import to reduce initial bundle weight
  • Preload critical LCP resources and reserve space to avoid layout shifts

Example use cases

  • Audit a production page to reach Lighthouse performance ≥90 and CWV in the Good range
  • Analyze a Next.js build to reduce unused JavaScript and optimize Image usage
  • Profile a slow interaction to find and split long tasks causing high INP/TTI
  • Produce a prioritized report for a sprint: top 3 fixes with estimated impact and implementation steps
  • Verify caching, preload, and font strategies before a release

FAQ

What metrics does the skill report on?

It reports Lighthouse category scores plus Core Web Vitals (LCP, INP, CLS) and complementary metrics like FCP and TTFB.

How do I get consistent results?

Run multiple audits, use a controlled environment (headed/headless Chrome), and apply throttling settings; compare lab data to CrUX for field validation.