profiling-performance
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:
# URL to audit
TARGET_URL="https://example.com"
For local development:
# Ensure dev server is running
npm run dev
TARGET_URL="http://localhost:3000"
For static build analysis:
npm run build
npx serve dist # or out, build folder
Step 2: Run Lighthouse Audit
CLI audit:
npx lighthouse $TARGET_URL --output=json --output=html --output-path=./lighthouse-report
With specific categories:
npx lighthouse $TARGET_URL --only-categories=performance,accessibility,best-practices,seo --output=json
Mobile emulation (default):
npx lighthouse $TARGET_URL --preset=desktop # For desktop metrics
Programmatic in Node.js:
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:
ANALYZE=true npm run build
# Or add to next.config.js:
# const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true' });
Vite/Nuxt:
npx vite-bundle-visualizer
# Or
npx nuxi analyze
Generic webpack:
npx webpack-bundle-analyzer stats.json
Source map explorer:
npx source-map-explorer dist/**/*.js
Step 5: Profile Runtime Performance
Chrome DevTools Performance tab:
- Open DevTools → Performance
- Click Record
- Perform user actions
- Stop recording
- Analyze flame chart for long tasks
Measure in code:
// 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:
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:
## 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
// 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
// React - Lazy load heavy components
import { lazy, Suspense } from "react";
const HeavyChart = lazy(() => import("./HeavyChart"));
<Suspense fallback={<Loading />}>
<HeavyChart />
</Suspense>;
// Dynamic import for conditional features
const module = await import("./heavy-module");
Font Optimization
// Next.js - Use next/font
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], display: "swap" });
/* Self-hosted with font-display */
@font-face {
font-family: "Custom";
src: url("/fonts/custom.woff2") format("woff2");
font-display: swap;
}
Preloading Critical Resources
<!-- 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
/* Reserve space for images */
img {
aspect-ratio: 16 / 9;
width: 100%;
height: auto;
}
/* Reserve space for ads/embeds */
.ad-slot {
min-height: 250px;
}
// Always provide width/height
<Image width={800} height={450} ... />
Caching
// 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
More from wesleysmits/agent-skills
writing-product-descriptions
Creates compelling product copy for e-commerce listings. Use when the user asks about product descriptions, e-commerce copy, product pages, marketplace listings, or converting features to benefits.
20writing-long-form-content
Generates comprehensive blog post drafts with proper structure. Use when the user asks to write a full article, create blog content, draft long-form posts, or needs complete written content with SEO optimization.
15writing-youtube-video-scripts
Creates structured video scripts with hooks, segments, and CTAs. Use when the user asks about YouTube scripts, video content, video outlines, talking points, or video intros.
15writing-press-releases
Generates professional press releases with headline, dateline, inverted pyramid structure, and boilerplate. Use when the user asks about press releases, media announcements, news releases, PR distribution, or journalist outreach.
11generating-ebooks-and-lead-magnets
Creates comprehensive ebooks, guides, and downloadable lead magnets with chapter structure and promotional assets. Use when the user asks about ebooks, lead magnets, downloadable guides, gated content, or PDF resources.
11researching-seo-keywords
Expands keyword lists and analyzes search intent for content strategy. Use when the user asks about keyword research, search intent, long-tail keywords, keyword gaps, or SEO content planning.
8