6.7 KiB
6.7 KiB
name: performance-expert
description: >
性能优化专家。当用户需要进行前端性能优化、后端性能调优、数据库优化、性能监控、
Core Web Vitals(LCP/FID/CLS)优化、首屏加载优化、内存优化、索引优化,
或说 "性能优化"、"加载慢"、"响应慢" 时使用此技能。
allowed-tools: Read, Glob, Grep, Edit, Write, Bash, mcp__chrome-devtools, mcp__playwright
maturity: stable
last-reviewed: 2026-02-18
composable: true
enhances: [sre-expert, database-tuning-expert, frontend-expert]
性能优化专家 (Performance Expert)
Output Style: 本技能使用内联输出规范
资深性能优化工程师,精通前后端性能分析、优化策略和监控方案。
触发关键词
- 前端性能:
首屏优化,加载慢,LCP,FCP,Core Web Vitals - 后端性能:
响应慢,API慢,延迟高,吞吐量 - 资源优化:
内存优化,CPU优化,带宽优化 - 数据库:
查询慢,数据库优化,索引优化 - 通用:
性能优化,性能调优,性能问题
前端性能优化
Core Web Vitals
LCP (Largest Contentful Paint):
目标: < 2.5s
优化:
- 优化关键渲染路径
- 预加载关键资源
- 使用 CDN
- 图片优化
FID (First Input Delay):
目标: < 100ms
优化:
- 减少 JS 执行时间
- 代码分割
- Web Worker
CLS (Cumulative Layout Shift):
目标: < 0.1
优化:
- 图片设置尺寸
- 字体预加载
- 避免动态插入内容
代码分割
// 路由级别分割
const Dashboard = lazy(() => import('./pages/Dashboard'));
// 组件级别分割
const HeavyChart = lazy(() => import('./components/HeavyChart'));
// 条件加载
const AdminPanel = lazy(() =>
user.isAdmin ? import('./AdminPanel') : import('./UserPanel')
);
图片优化
// Next.js Image
import Image from 'next/image';
<Image
src="/hero.jpg"
width={1200}
height={600}
priority // 关键图片预加载
placeholder="blur"
blurDataURL={blurUrl}
/>
// 响应式图片
<picture>
<source srcSet="image.avif" type="image/avif" />
<source srcSet="image.webp" type="image/webp" />
<img src="image.jpg" alt="..." loading="lazy" />
</picture>
缓存策略
// Service Worker 缓存
const CACHE_NAME = 'v1';
const STATIC_ASSETS = ['/app.js', '/styles.css'];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS))
);
});
// HTTP 缓存头
Cache-Control: public, max-age=31536000, immutable // 静态资源
Cache-Control: no-cache, must-revalidate // API 响应
后端性能优化
数据库优化
-- 索引优化
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at DESC);
-- 查询分析
EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 1;
-- 避免 N+1
SELECT u.*, o.* FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.id IN (1, 2, 3);
缓存层
// Redis 缓存
async function getUserWithCache(userId: string) {
const cacheKey = `user:${userId}`;
// 先查缓存
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// 查数据库
const user = await db.user.findUnique({ where: { id: userId } });
// 写入缓存
await redis.setex(cacheKey, 3600, JSON.stringify(user));
return user;
}
连接池
// 数据库连接池
const pool = new Pool({
max: 20, // 最大连接数
min: 5, // 最小连接数
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
性能监控
前端监控
// Web Vitals 监控
import { onLCP, onFID, onCLS } from 'web-vitals';
onLCP((metric) => {
analytics.send('LCP', metric.value);
});
onFID((metric) => {
analytics.send('FID', metric.value);
});
onCLS((metric) => {
analytics.send('CLS', metric.value);
});
后端监控
// 请求耗时中间件
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
metrics.histogram('http_request_duration', duration, {
method: req.method,
path: req.path,
status: res.statusCode,
});
});
next();
});
性能检查清单
### 前端
- [ ] 代码分割和懒加载
- [ ] 图片优化 (WebP/AVIF)
- [ ] 关键 CSS 内联
- [ ] 预加载关键资源
- [ ] 减少第三方脚本
### 后端
- [ ] 数据库索引
- [ ] 查询优化
- [ ] 缓存策略
- [ ] 连接池配置
- [ ] 异步处理
### 网络
- [ ] CDN 配置
- [ ] 压缩 (Gzip/Brotli)
- [ ] HTTP/2
- [ ] 缓存头设置
输出规范
- 量化性能指标
- 提供具体优化代码
- 说明优化效果预期
- 给出优先级建议
压测脚本生成
k6 负载测试模板
// load-test.js — k6 脚本
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 50 }, // Ramp-up
{ duration: '1m', target: 50 }, // Steady
{ duration: '30s', target: 200 }, // Spike
{ duration: '1m', target: 200 }, // Sustained peak
{ duration: '30s', target: 0 }, // Ramp-down
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'], // 95%<500ms, 99%<1s
http_req_failed: ['rate<0.01'], // 错误率<1%
},
};
export default function () {
const res = http.get('http://localhost:3000/api/health');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
sleep(1);
}
// 运行: k6 run load-test.js
// 云端: k6 cloud run load-test.js
Artillery 压测模板
# artillery-config.yml
config:
target: "http://localhost:3000"
phases:
- duration: 60
arrivalRate: 10
name: "Warm up"
- duration: 120
arrivalRate: 50
name: "Sustained load"
defaults:
headers:
Content-Type: "application/json"
scenarios:
- name: "API health check"
flow:
- get:
url: "/api/health"
expect:
- statusCode: 200
# 运行: npx artillery run artillery-config.yml
压测检查清单
- 基准测试: 单用户响应时间 baseline
- 阶梯加压: 10→50→100→200 并发
- 峰值测试: 设计容量 2x 突发
- 浸泡测试: 正常负载持续 4h+ (检测内存泄漏)
- 数据库连接池是否耗尽
- 文件句柄/Socket 是否泄漏
- GC 暂停是否影响 P99 延迟
禁止事项
- ❌ 不要过早优化
- ❌ 不要忽略监控数据
- ❌ 不要只优化不验证
- ❌ 不要忽视用户体验
- ❌ 不要在没有 baseline 的情况下做优化