The prerequisite for optimization is measurement. If you don't know where the slowness is, you don't know what to optimize. Every optimization must have a "before" and "after" data comparison, otherwise it doesn't count as optimization.
Step 1: Clarify the analysis goal
性能问题
│
├─ 前端性能?(页面加载慢、交互卡顿、首屏慢)
│ └─ 前端分析流程
│
├─ 后端性能?(API 响应慢、数据库查询慢、CPU/内存高)
│ └─ 后端分析流程
│
└─ 不确定?
└─ 先用浏览器 DevTools Network 面板判断瓶颈在前端还是后端
Use AskUserQuestion to confirm:
- Specific symptoms: Where is it slow? How slow is it? (Want data, not "feelings")
- Performance baseline: What is it currently? What is the target?
- Reproduction conditions: Specific page? Specific data volume? Specific concurrency?
Frontend Performance Analysis
2.1 Core Web Vitals Measurement
| Metric | Meaning | Good | Needs Improvement | Poor |
|---|---|---|---|---|
| LCP | Largest Contentful Paint | ≤2.5s | ≤4s | >4s |
| INP | First Input Delay | ≤200ms | ≤500ms | >500ms |
| CLS | Cumulative Layout Shift | ≤0.1 | ≤0.25 | >0.25 |
Measurement tools:
# Lighthouse CLI(如果可用)
npx lighthouse <url> --output=json --output-path=./lighthouse-report.json
# 或用 Playwright 采集性能数据
# 通过 MCP playwright 工具访问页面并执行 performance API
2.2 Bundle Analysis
# Webpack
npx webpack-bundle-analyzer stats.json
# Vite
npx vite-bundle-visualizer
# Next.js
ANALYZE=true next build
Points of focus:
- Total bundle size (after gzip)
- Proportion of the largest few dependencies
- Whether there are duplicated bundled dependencies
- Whether code splitting is done
2.3 Common Frontend Bottlenecks and Optimization Directions
| Bottleneck | Diagnosis method | Optimization direction |
|---|---|---|
| Large above-the-fold images/large resources blocking LCP | Lighthouse / Network waterfall | Lazy loading, compression, CDN, preload critical resources |
| JS Bundle too large | Bundle analysis | Code splitting, tree shaking, dynamic imports |
| Unoptimized images | Lighthouse image audit | WebP/AVIF, responsive images, compression |
| Layout thrashing causing CLS | Lighthouse CLS audit | Fixed-size placeholders, font preloading |
| Large number of DOM operations | Performance timeline | Virtual lists, reduce reflows, requestAnimationFrame |
| Third-party scripts blocking | Network + Coverage | Lazy loading, asynchronous loading, remove unnecessary third-party scripts |
Backend Performance Analysis
3.1 API Response Time Measurement
# 简单测量(单次)
time curl -s -o /dev/null -w "%{time_total}" <api-url>
# 并发测试(如 wrk 可用)
wrk -t4 -c100 -d30s <api-url>
# 或用 Node.js 脚本测量
node -e "
const start = Date.now();
fetch('<api-url>').then(() => console.log(Date.now() - start + 'ms'));
"
Record key metrics:
- p50 / p95 / p99 response time
- Throughput (req/s)
- Error rate
3.2 Database Query Analysis
-- MySQL/PostgreSQL 查询分析
EXPLAIN ANALYZE <your-query>;
// Node.js ORM 慢查询日志
// Prisma: 在 PrismaClient 初始化时开启
const prisma = new PrismaClient({ log: ['query', 'warn', 'error'] });
// Sequelize: 开启 benchmark
const sequelize = new Sequelize({ benchmark: true, logging: console.log });
Points of focus:
- Full table scans (missing indexes)
- N+1 queries
- Unused indexes
- Slow queries (>100ms)
3.3 Node.js / Python Profiling
Node.js:
# CPU profiling
node --prof app.js
node --prof-process isolate-xxx.log > processed.txt
# 内存快照
node --inspect app.js
# 然后在 Chrome DevTools 中 Take Heap Snapshot
Python:
# cProfile
python -m cProfile -s cumtime app.py
# memory_profiler
pip install memory_profiler
python -m memory_profiler app.py
3.4 Common Backend Bottlenecks and Optimization Directions
| Bottleneck | Diagnosis method | Optimization direction |
|---|---|---|
| Slow database queries | EXPLAIN ANALYZE | Add indexes, optimize queries, reduce N+1 |
| Serialization/deserialization overhead | profiling | Reduce response fields, pagination, caching |
| External API calls blocking | timing logs | Parallel invocation, caching, timeout control |
| Memory leak | Memory snapshot comparison | Investigate unreleased references and closures |
| CPU-intensive computation | CPU profiling | Worker threads, caching computation results |
| Connection pool exhaustion | Connection pool monitoring | Adjust pool size, check for connection leaks |
Step 4: Optimization and Comparison
4.1 Record the Baseline Before Optimization
Before making any changes,you must record the current performance data:
## 性能基线(优化前)
| 指标 | 值 | 测量条件 |
|------|-----|---------|
| LCP | 3.8s | 首页,Chrome,4G 模拟 |
| API /users 响应 | p95: 450ms | 100 并发,30s |
| 数据库查询 | 320ms | users 表 10 万行 |
4.2 Comparison After Optimization
After each optimization, usethe same conditionsto re-measure and compare before and after:
## 优化效果对比
| 指标 | 优化前 | 优化后 | 改善 |
|------|--------|--------|------|
| LCP | 3.8s | 1.9s | -50% ✅ |
| API /users p95 | 450ms | 120ms | -73% ✅ |
| Bundle 大小 | 2.1MB | 890KB | -58% ✅ |
4.3 Output the Performance Report
After a complete performance analysis, output the report to docs/specs/ or provide it directly in the conversation:
# 性能分析报告:<模块/页面>
## 问题描述
用户反馈/指标异常的具体描述
## 分析结论
瓶颈在哪,为什么慢
## 优化措施
| # | 措施 | 预期效果 | 实际效果 |
|---|------|---------|---------|
## 性能对比
基线 vs 优化后
## 后续建议
还可以进一步优化的方向
Analysis Guidelines
- Data-driven: Do not optimize based on intuition. Measure first, find the bottleneck, optimize, then measure again
- Priority: Optimize the bottlenecks with the greatest impact first (the 80/20 rule)
- Choose tools based on the project: Do not mandate a particular tool; use whatever is available in the project, and recommend installing what is missing
- Do not over-optimize: Stop once the goal is reached. The cost of optimizing from 3s to 2s and from 2s to 1.5s is completely different
- Regression protection: Performance optimization must not break functionality. After optimization, you must run tests to confirm that functionality works properly
Relationship with Other Skills
task-execute 执行中发现性能问题 → perf-profiling(分析定位)
refactoring 重构后 → perf-profiling(回归验证,确认性能没退化)
release 发版前 → perf-profiling(性能相关需求的验收)