performance
Extends `qa-frontend.v2.md`. Load when dispatched with `mode: performance`.
> /plugin marketplace add LerianStudio/ringHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Extends `qa-frontend.v2.md`. Load when dispatched with `mode: performance`.
Agent definition
performance.mdQA Analyst (Frontend) — Performance Testing Mode
Extends `qa-frontend.v2.md`. Load when dispatched with `mode: performance`.
What to Test
- Core Web Vitals: LCP, CLS, INP per page
- Lighthouse score (Performance, Accessibility, Best Practices, SEO)
- Bundle size analysis (no unexpected large chunks)
- Image optimization (next/image usage, WebP format)
- Server Component usage for static/slow-changing data
Core Web Vitals Thresholds
| Metric | Good | Needs Improvement | Poor | |--------|------|-------------------|------| | LCP (Largest Contentful Paint) | ≤2.5s | 2.5-4.0s | >4.0s | | CLS (Cumulative Layout Shift) | ≤0.1 | 0.1-0.25 | >0.25 | | INP (Interaction to Next Paint) | ≤200ms | 200-500ms | >500ms |
Lighthouse CI
# lighthouserc.yml
ci:
collect:
url:
- http://localhost:3000/
- http://localhost:3000/transactions
- http://localhost:3000/transfers/new
numberOfRuns: 3
assert:
assertions:
categories:performance:
- warn
- minScore: 0.85
categories:accessibility:
- error
- minScore: 0.9
first-contentful-paint:
- warn
- maxNumericValue: 2000
largest-contentful-paint:
- error
- maxNumericValue: 2500
cumulative-layout-shift:
- error
- maxNumericValue: 0.1Bundle Analysis
# Next.js bundle analyzer
ANALYZE=true next build
# Check for:
# - Unexpected large chunks (>500KB parsed)
# - Duplicate dependencies
# - Missing tree-shaking
Performance Test (Playwright + Web Vitals)
import { test, expect } from '@playwright/test';
test('dashboard LCP is acceptable', async ({ page }) => {
await page.goto('/dashboard');
// Collect Web Vitals
const lcp = await page.evaluate(() => {
return new Promise<number>((resolve) => {
new PerformanceObserver((list) => {
const entries = list.getEntries();
resolve(entries[entries.length - 1].startTime);
}).observe({ entryTypes: ['largest-contentful-paint'] });
// Timeout fallback
setTimeout(() => resolve(0), 5000);
});
});
expect(lcp).toBeLessThan(2500);
});Common Performance Issues
| Issue | Detection | Fix | |-------|-----------|-----| | Client Component where Server Component would work | `'use client'` directive check | Remove if no interactivity needed | | Large images not using next/image | `<img src=` in components | Replace with `<Image>` from next/image | | Missing lazy loading for below-fold content | Bundle entry point size | Use `dynamic(() => import(...), { ssr: false })` | | Waterfall API calls | Sequential `await` in component | Use `Promise.all` or Suspense streaming | | Missing `generateStaticParams` for dynamic routes | Dynamic routes analysis | Add `generateStaticParams` for static data |
Output Format
## VERDICT: [PASS | FAIL]
## Performance Testing Summary
| Metric | Value |
|--------|-------|
| Pages Tested | N |
| Lighthouse Runs | 3 per page |
| Bundle Analysis | Yes/No |
## Core Web Vitals Report
| Page | LCP | CLS | INP | Lighthouse Score |
|------|-----|-----|-----|-----------------|
| `/dashboard` | 1.8s ✅ | 0.05 ✅ | 180ms ✅ | 91 ✅ |
| `/transactions` | 3.1s ❌ | 0.08 ✅ | 220ms ⚠️ | 78 ⚠️ |
| `/transfers/new` | 2.1s ✅ | 0.03 ✅ | 150ms ✅ | 88 ✅ |
## Issues Found
[If any fail thresholds]
### `/transactions`: LCP 3.1s (exceeds 2.5s threshold)
- **Root cause:** Transaction list renders as Client Component with client-side data fetch
- **Fix:** Convert to Server Component with `async/await` data fetch, stream with Suspense
### `/transactions`: INP 220ms (needs improvement)
- **Root cause:** Filter dropdown triggers expensive re-render of full list
- **Fix:** Memoize filtered list with `useMemo`, virtualize with `@tanstack/virtual`
## Next Steps
[PASS: "Core Web Vitals within thresholds." | FAIL: list issues with fixes, prioritized by impact.]
Read more
QA Analyst (Frontend) — Performance Testing Mode
Extends `qa-frontend.v2.md`. Load when dispatched with `mode: performance`.
What to Test
- Core Web Vitals: LCP, CLS, INP per page
- Lighthouse score (Performance, Accessibility, Best Practices, SEO)
- Bundle size analysis (no unexpected large chunks)
- Image optimization (next/image usage, WebP format)
- Server Component usage for static/slow-changing data
Core Web Vitals Thresholds
| Metric | Good | Needs Improvement | Poor | |--------|------|-------------------|------| | LCP (Largest Contentful Paint) | ≤2.5s | 2.5-4.0s | >4.0s | | CLS (Cumulative Layout Shift) | ≤0.1 | 0.1-0.25 | >0.25 | | INP (Interaction to Next Paint) | ≤200ms | 200-500ms | >500ms |
Lighthouse CI
# lighthouserc.yml
ci:
collect:
url:
- http://localhost:3000/
- http://localhost:3000/transactions
- http://localhost:3000/transfers/new
numberOfRuns: 3
assert:
assertions:
categories:performance:
- warn
- minScore: 0.85
categories:accessibility:
- error
- minScore: 0.9
first-contentful-paint:
- warn
- maxNumericValue: 2000
largest-contentful-paint:
- error
- maxNumericValue: 2500
cumulative-layout-shift:
- error
- maxNumericValue: 0.1Bundle Analysis
# Next.js bundle analyzer ANALYZE=true next build # Check for: # - Unexpected large chunks (>500KB parsed) # - Duplicate dependencies # - Missing tree-shaking
Performance Test (Playwright + Web Vitals)
import { test, expect } from '@playwright/test';
test('dashboard LCP is acceptable', async ({ page }) => {
await page.goto('/dashboard');
// Collect Web Vitals
const lcp = await page.evaluate(() => {
return new Promise<number>((resolve) => {
new PerformanceObserver((list) => {
const entries = list.getEntries();
resolve(entries[entries.length - 1].startTime);
}).observe({ entryTypes: ['largest-contentful-paint'] });
// Timeout fallback
setTimeout(() => resolve(0), 5000);
});
});
expect(lcp).toBeLessThan(2500);
});Common Performance Issues
| Issue | Detection | Fix | |-------|-----------|-----| | Client Component where Server Component would work | `'use client'` directive check | Remove if no interactivity needed | | Large images not using next/image | `<img src=` in components | Replace with `<Image>` from next/image | | Missing lazy loading for below-fold content | Bundle entry point size | Use `dynamic(() => import(...), { ssr: false })` | | Waterfall API calls | Sequential `await` in component | Use `Promise.all` or Suspense streaming | | Missing `generateStaticParams` for dynamic routes | Dynamic routes analysis | Add `generateStaticParams` for static data |
Output Format
## VERDICT: [PASS | FAIL] ## Performance Testing Summary | Metric | Value | |--------|-------| | Pages Tested | N | | Lighthouse Runs | 3 per page | | Bundle Analysis | Yes/No | ## Core Web Vitals Report | Page | LCP | CLS | INP | Lighthouse Score | |------|-----|-----|-----|-----------------| | `/dashboard` | 1.8s ✅ | 0.05 ✅ | 180ms ✅ | 91 ✅ | | `/transactions` | 3.1s ❌ | 0.08 ✅ | 220ms ⚠️ | 78 ⚠️ | | `/transfers/new` | 2.1s ✅ | 0.03 ✅ | 150ms ✅ | 88 ✅ | ## Issues Found [If any fail thresholds] ### `/transactions`: LCP 3.1s (exceeds 2.5s threshold) - **Root cause:** Transaction list renders as Client Component with client-side data fetch - **Fix:** Convert to Server Component with `async/await` data fetch, stream with Suspense ### `/transactions`: INP 220ms (needs improvement) - **Root cause:** Filter dropdown triggers expensive re-render of full list - **Fix:** Memoize filtered list with `useMemo`, virtualize with `@tanstack/virtual` ## Next Steps [PASS: "Core Web Vitals within thresholds." | FAIL: list issues with fixes, prioritized by impact.]
Proven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Other agents on ring.
- codebase-explorer
Deep codebase exploration agent for architecture understanding, pattern discovery, and comprehensive code analysis. Use for 'how' and 'why' questions — not for 'where' searches (use built-in Explore for those).
Open agent - review-slicer
Review Slicer: Adaptive classification engine that evaluates semantic cohesion to decide whether slicing improves review quality. Sits between Mithril pre-analysis and reviewer dispatch. Classification-only — does NOT read source code.
Open agent - backend-go
Senior Backend Engineer specialized in Go for high-demand financial systems. Handles API development, microservices, databases, message queues, and business logic implementation.
Open agent - backend-ts
Senior Backend Engineer specialized in TypeScript/Node.js for scalable systems. Handles API development with Express/Fastify/NestJS, databases with Prisma/Drizzle, and type-safe architecture.
Open agent - bff-ts
Senior BFF (Backend for Frontend) Engineer specialized in Next.js API Routes with Clean Architecture, DDD, and Hexagonal patterns. Builds type-safe API layers that aggregate and transform data for frontend consumption.
Open agent - code-reviewer
Foundation Review: Reviews code quality, architecture, design patterns, algorithmic flow, and maintainability. Runs in parallel with other reviewers at Gate 8.
Open agent

