perf-analyzer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Analyzer Skill
Performance Analyzer 技能
Purpose
用途
Analyzes frontend application performance and suggests optimizations for bundle size, rendering, and images.
分析前端应用性能,并针对包体积、渲染和图片提供优化建议。
When to Use
适用场景
- Performance analysis requests
- "Slow", "long loading" mentions
- Bundle size, rendering, Core Web Vitals questions
- Pre-production performance review
- 性能分析请求
- 提及“缓慢”、“加载时间长”的场景
- 关于包体积、渲染、Core Web Vitals的问题
- 预生产环境性能评审
Workflow
工作流程
Step 1: Select Analysis Areas
步骤1:选择分析领域
AskUserQuestion:
"Which areas to analyze?"
Options:
- Full performance analysis (recommended)
- Bundle size analysis
- Rendering performance (re-renders)
- Image/asset optimization
- Code splitting opportunities
multiSelect: true向用户提问:
“需要分析哪些领域?”
选项:
- 全面性能分析(推荐)
- 包体积分析
- 渲染性能(重渲染)
- 图片/资源优化
- 代码分割机会
可多选: trueAnalysis Areas
分析领域
Bundle Size
包体积
| Item | Threshold | Severity |
|---|---|---|
| Total bundle | > 500KB | HIGH |
| Initial JS | > 200KB | HIGH |
| Single chunk | > 100KB | MEDIUM |
| Unused code | Tree-shaking failures | MEDIUM |
Large Dependencies:
typescript
// WARNING: Large libraries
import _ from 'lodash' // 71KB
import moment from 'moment' // 280KB
// BETTER: Lightweight alternatives
import debounce from 'lodash/debounce' // 2KB
import { format } from 'date-fns' // Only needed functionsTree-shaking Issues:
typescript
// BAD: Full import (no tree-shaking)
import * as utils from './utils'
// GOOD: Named import
import { specificFunction } from './utils'| 项目 | 阈值 | 严重程度 |
|---|---|---|
| 总包体积 | > 500KB | 高 |
| 初始JS体积 | > 200KB | 高 |
| 单个代码块 | > 100KB | 中 |
| 未使用代码 | Tree-shaking失败 | 中 |
大依赖项:
typescript
// 警告:大型库
import _ from 'lodash' // 71KB
import moment from 'moment' // 280KB
// 推荐:轻量替代方案
import debounce from 'lodash/debounce' // 2KB
import { format } from 'date-fns' // 仅导入所需函数Tree-shaking问题:
typescript
// 不良实践:全量导入(无法Tree-shaking)
import * as utils from './utils'
// 推荐:命名导入
import { specificFunction } from './utils'Rendering Performance
渲染性能
Unnecessary Re-renders:
typescript
// WARNING: New object/array every render
function Component() {
return <Child style={{ color: 'red' }} /> // New object each time
}
// BETTER: External definition
const style = { color: 'red' }
function Component() {
return <Child style={style} />
}Expensive Computations:
typescript
// WARNING: Computed every render
function Component({ data }) {
const processed = data.map(item => expensiveOp(item))
return <List items={processed} />
}
// BETTER: useMemo caching
const processed = useMemo(
() => data.map(item => expensiveOp(item)),
[data]
)Callback Optimization:
typescript
// WARNING: New function every render
<Child onClick={() => handleClick()} />
// BETTER: useCallback
const handleClick = useCallback(() => { /* ... */ }, [])
<Child onClick={handleClick} />不必要的重渲染:
typescript
// 警告:每次渲染创建新对象/数组
function Component() {
return <Child style={{ color: 'red' }} /> // 每次渲染创建新对象
}
// 推荐:外部定义
const style = { color: 'red' }
function Component() {
return <Child style={style} />
}高开销计算:
typescript
// 警告:每次渲染都执行计算
function Component({ data }) {
const processed = data.map(item => expensiveOp(item))
return <List items={processed} />
}
// 推荐:使用useMemo缓存
const processed = useMemo(
() => data.map(item => expensiveOp(item)),
[data]
)回调函数优化:
typescript
// 警告:每次渲染创建新函数
<Child onClick={() => handleClick()} />
// 推荐:使用useCallback
const handleClick = useCallback(() => { /* ... */ }, [])
<Child onClick={handleClick} />Image Optimization
图片优化
| Issue | Problem | Solution |
|---|---|---|
| Large image | > 200KB | Compress or WebP |
| Unoptimized format | PNG/JPG | WebP/AVIF |
| Missing lazy load | Offscreen images | loading="lazy" |
| Fixed size | Non-responsive | srcset/sizes |
typescript
// BAD: No optimization
<img src="/hero.jpg" alt="Hero" />
// GOOD: next/image
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // LCP image
placeholder="blur"
/>| 问题 | 影响 | 解决方案 |
|---|---|---|
| 图片过大 | > 200KB | 压缩或转换为WebP格式 |
| 格式未优化 | PNG/JPG | 转换为WebP/AVIF格式 |
| 缺少懒加载 | 屏幕外图片未延迟加载 | 添加loading="lazy"属性 |
| 固定尺寸 | 非响应式 | 使用srcset/sizes属性 |
typescript
// 不良实践:无优化
<img src="/hero.jpg" alt="Hero" />
// 推荐:使用next/image
<Image
src="/hero.jpg"
alt="Hero"
width={1200}
height={600}
priority // LCP图片
placeholder="blur"
/>Code Splitting
代码分割
typescript
// WARNING: Unnecessary initial load
import HeavyComponent from './HeavyComponent'
// BETTER: Load on demand
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />
})typescript
// 警告:不必要的初始加载
import HeavyComponent from './HeavyComponent'
// 推荐:按需加载
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />
})Core Web Vitals
Core Web Vitals
LCP (Largest Contentful Paint)
| Grade | Time | Improvements |
|---|---|---|
| Good | < 2.5s | - |
| Needs Work | 2.5-4s | Image optimization, server response |
| Poor | > 4s | CDN, caching, code splitting |
FID (First Input Delay)
| Grade | Time | Improvements |
|---|---|---|
| Good | < 100ms | - |
| Needs Work | 100-300ms | Reduce main thread blocking |
| Poor | > 300ms | Split long tasks, Web Workers |
CLS (Cumulative Layout Shift)
| Grade | Score | Improvements |
|---|---|---|
| Good | < 0.1 | - |
| Needs Work | 0.1-0.25 | Specify image/font dimensions |
| Poor | > 0.25 | Reserve space for dynamic content |
LCP(最大内容绘制)
| 评级 | 时间 | 优化方向 |
|---|---|---|
| 良好 | < 2.5秒 | - |
| 需要改进 | 2.5-4秒 | 图片优化、服务器响应速度提升 |
| 较差 | > 4秒 | 使用CDN、缓存、代码分割 |
FID(首次输入延迟)
| 评级 | 时间 | 优化方向 |
|---|---|---|
| 良好 | < 100毫秒 | - |
| 需要改进 | 100-300毫秒 | 减少主线程阻塞 |
| 较差 | > 300毫秒 | 拆分长任务、使用Web Workers |
CLS(累积布局偏移)
| 评级 | 分数 | 优化方向 |
|---|---|---|
| 良好 | < 0.1 | - |
| 需要改进 | 0.1-0.25 | 指定图片/字体尺寸 |
| 较差 | > 0.25 | 为动态内容预留空间 |
Response Template
响应模板
undefinedundefinedPerformance Analysis Results
性能分析结果
Project: [name]
项目: [名称]
Bundle Size
包体积
| Item | Size | Status |
|---|---|---|
| Total bundle | 650KB | WARNING |
| Initial JS | 180KB | OK |
Large Dependencies:
| Package | Size | Alternative |
|---|---|---|
| moment | 280KB | date-fns (7KB) |
| lodash | 71KB | lodash-es + individual imports |
| 项目 | 大小 | 状态 |
|---|---|---|
| 总包体积 | 650KB | 警告 |
| 初始JS体积 | 180KB | 正常 |
大依赖项:
| 包 | 大小 | 替代方案 |
|---|---|---|
| moment | 280KB | date-fns (7KB) |
| lodash | 71KB | lodash-es + 单独导入 |
Rendering Performance
渲染性能
| Component | Issue | Recommendation |
|---|---|---|
| ProductList | Unnecessary re-renders | Add useMemo |
| 组件 | 问题 | 建议 |
|---|---|---|
| ProductList | 不必要的重渲染 | 添加useMemo |
Image Optimization
图片优化
| Image | Size | Recommendation |
|---|---|---|
| hero.jpg | 450KB | Convert to WebP, use next/image |
| 图片 | 大小 | 建议 |
|---|---|---|
| hero.jpg | 450KB | 转换为WebP格式,使用next/image |
Code Splitting Opportunities
代码分割机会
| Component | Size | Recommendation |
|---|---|---|
| Dashboard | 85KB | dynamic import |
| 组件 | 大小 | 建议 |
|---|---|---|
| Dashboard | 85KB | 动态导入 |
Priority Actions
优先级行动项
- moment → date-fns migration (-273KB)
- Add useMemo to ProductList
- Convert hero.jpg to WebP
- Dynamic import Dashboard
- 迁移moment至date-fns (-273KB)
- 为ProductList添加useMemo
- 将hero.jpg转换为WebP格式
- 动态导入Dashboard组件
Expected Improvements
预期提升效果
- Initial bundle: 650KB → ~350KB (-46%)
- LCP: Expected improvement
- TTI: Expected improvement
undefined- 初始包体积:650KB → ~350KB (-46%)
- LCP:预计提升
- TTI:预计提升
undefinedBest Practices
最佳实践
- Measure First: Always measure before optimizing
- Incremental: Apply one change at a time
- Trade-offs: Avoid over-optimization
- Real Device Testing: Test on low-end devices
- Continuous Monitoring: Prevent performance regression
- 先测量再优化:优化前务必先进行性能测量
- 逐步优化:每次只应用一项变更
- 权衡取舍:避免过度优化
- 真实设备测试:在低端设备上进行测试
- 持续监控:防止性能退化
Integration
集成
- skill
code-reviewer - skill
nextjs-reviewer - command
/analyze-code
- 技能
code-reviewer - 技能
nextjs-reviewer - 命令
/analyze-code
Notes
注意事项
- Static analysis based, runtime performance may differ
- Use with Lighthouse for actual measurements
- Analyze production builds
- 基于静态分析,运行时性能可能有所不同
- 建议结合Lighthouse进行实际测量
- 分析生产环境构建产物