perf-analyzer

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Performance 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
向用户提问:
“需要分析哪些领域?”
选项:
- 全面性能分析(推荐)
- 包体积分析
- 渲染性能(重渲染)
- 图片/资源优化
- 代码分割机会
可多选: true

Analysis Areas

分析领域

Bundle Size

包体积

ItemThresholdSeverity
Total bundle> 500KBHIGH
Initial JS> 200KBHIGH
Single chunk> 100KBMEDIUM
Unused codeTree-shaking failuresMEDIUM
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 functions
Tree-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

图片优化

IssueProblemSolution
Large image> 200KBCompress or WebP
Unoptimized formatPNG/JPGWebP/AVIF
Missing lazy loadOffscreen imagesloading="lazy"
Fixed sizeNon-responsivesrcset/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)
GradeTimeImprovements
Good< 2.5s-
Needs Work2.5-4sImage optimization, server response
Poor> 4sCDN, caching, code splitting
FID (First Input Delay)
GradeTimeImprovements
Good< 100ms-
Needs Work100-300msReduce main thread blocking
Poor> 300msSplit long tasks, Web Workers
CLS (Cumulative Layout Shift)
GradeScoreImprovements
Good< 0.1-
Needs Work0.1-0.25Specify image/font dimensions
Poor> 0.25Reserve 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

响应模板

undefined
undefined

Performance Analysis Results

性能分析结果

Project: [name]
项目: [名称]

Bundle Size

包体积

ItemSizeStatus
Total bundle650KBWARNING
Initial JS180KBOK
Large Dependencies:
PackageSizeAlternative
moment280KBdate-fns (7KB)
lodash71KBlodash-es + individual imports
项目大小状态
总包体积650KB警告
初始JS体积180KB正常
大依赖项:
大小替代方案
moment280KBdate-fns (7KB)
lodash71KBlodash-es + 单独导入

Rendering Performance

渲染性能

ComponentIssueRecommendation
ProductListUnnecessary re-rendersAdd useMemo
组件问题建议
ProductList不必要的重渲染添加useMemo

Image Optimization

图片优化

ImageSizeRecommendation
hero.jpg450KBConvert to WebP, use next/image
图片大小建议
hero.jpg450KB转换为WebP格式,使用next/image

Code Splitting Opportunities

代码分割机会

ComponentSizeRecommendation
Dashboard85KBdynamic import
组件大小建议
Dashboard85KB动态导入

Priority Actions

优先级行动项

  1. moment → date-fns migration (-273KB)
  2. Add useMemo to ProductList
  3. Convert hero.jpg to WebP
  4. Dynamic import Dashboard
  1. 迁移moment至date-fns (-273KB)
  2. 为ProductList添加useMemo
  3. 将hero.jpg转换为WebP格式
  4. 动态导入Dashboard组件

Expected Improvements

预期提升效果

  • Initial bundle: 650KB → ~350KB (-46%)
  • LCP: Expected improvement
  • TTI: Expected improvement
undefined
  • 初始包体积:650KB → ~350KB (-46%)
  • LCP:预计提升
  • TTI:预计提升
undefined

Best Practices

最佳实践

  1. Measure First: Always measure before optimizing
  2. Incremental: Apply one change at a time
  3. Trade-offs: Avoid over-optimization
  4. Real Device Testing: Test on low-end devices
  5. Continuous Monitoring: Prevent performance regression
  1. 先测量再优化:优化前务必先进行性能测量
  2. 逐步优化:每次只应用一项变更
  3. 权衡取舍:避免过度优化
  4. 真实设备测试:在低端设备上进行测试
  5. 持续监控:防止性能退化

Integration

集成

  • code-reviewer
    skill
  • nextjs-reviewer
    skill
  • /analyze-code
    command
  • code-reviewer
    技能
  • nextjs-reviewer
    技能
  • /analyze-code
    命令

Notes

注意事项

  • Static analysis based, runtime performance may differ
  • Use with Lighthouse for actual measurements
  • Analyze production builds
  • 基于静态分析,运行时性能可能有所不同
  • 建议结合Lighthouse进行实际测量
  • 分析生产环境构建产物