performance-optimization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Optimization
性能优化
Overview
概述
Systematically identify and resolve performance bottlenecks using measurement-driven methodology. This skill enforces a strict MEASURE-IDENTIFY-OPTIMIZE-VERIFY cycle, preventing premature optimization and speculation. Every optimization must produce measurable improvement or be reverted.
Announce at start: "I'm using the performance-optimization skill to diagnose and resolve bottlenecks."
使用以数据测量为驱动的方法,系统性地识别并解决性能瓶颈。本技能严格遵循 MEASURE-IDENTIFY-OPTIMIZE-VERIFY(测量-识别-优化-验证)周期,避免过早优化和主观推测。每一项优化都必须产生可量化的改进,否则应当回退。
开始前声明: "我正在使用性能优化技能来诊断和解决瓶颈问题。"
Phase 1: MEASURE (Establish Baseline)
阶段1:测量(建立基准线)
Goal: Capture real metrics before changing anything.
目标: 在进行任何改动前采集真实指标。
Actions
操作
bash
undefinedbash
undefinedWeb: Lighthouse CI
Web: Lighthouse CI
npx lighthouse https://your-app.com --output=json --output-path=baseline.json
npx lighthouse https://your-app.com --output=json --output-path=baseline.json
API: load test with k6
API: load test with k6
k6 run --out json=baseline.json loadtest.js
k6 run --out json=baseline.json loadtest.js
Database: slow query log
Database: slow query log
PostgreSQL: SET log_min_duration_statement = 100; -- log queries > 100ms
PostgreSQL: SET log_min_duration_statement = 100; -- log queries > 100ms
Record these numbers. They are the baseline against which improvement is measured.
记录这些数值,它们是衡量改进效果的基准线。STOP — Do NOT proceed to Phase 2 until:
停止条件——满足以下条件前请勿进入阶段2:
- Baseline metrics are captured and saved
- Specific metric targets are defined (e.g., LCP < 2.5s)
- Measurement methodology is documented (so it can be repeated)
- 已采集并保存基准线指标
- 已定义明确的指标目标(例如LCP < 2.5s)
- 已记录测量方法(确保可重复执行)
Phase 2: IDENTIFY (Find the Actual Bottleneck)
阶段2:识别(找到真实瓶颈)
Goal: Use profiling tools to find WHERE time is spent. Do NOT guess.
目标: 使用分析工具找到耗时的真实位置,请勿主观猜测。
Profiling Tool Selection Table
分析工具选择表
| Layer | Tool | What It Shows |
|---|---|---|
| Frontend rendering | React DevTools Profiler, Chrome Performance tab | Component render times |
| Network | Chrome Network tab, WebPageTest | Request waterfall, TTFB |
| JavaScript | Chrome Performance tab, | Function execution time |
| Node.js server | | CPU flame graphs |
| Database | | Query plans, slow queries |
| Memory | Chrome Memory tab, heapdump | Allocation patterns, leaks |
| Bundle size | webpack-bundle-analyzer, vite-bundle-visualizer | Module sizes |
The bottleneck is almost never where you assume it is. Measure first.
| 层级 | 工具 | 可查看内容 |
|---|---|---|
| 前端渲染 | React DevTools Profiler, Chrome Performance tab | 组件渲染耗时 |
| 网络 | Chrome Network tab, WebPageTest | 请求瀑布流、TTFB |
| JavaScript | Chrome Performance tab, | 函数执行时间 |
| Node.js 服务端 | | CPU火焰图 |
| 数据库 | | 查询计划、慢查询 |
| 内存 | Chrome Memory tab, heapdump | 内存分配模式、泄漏问题 |
| 包体积 | webpack-bundle-analyzer, vite-bundle-visualizer | 模块大小 |
瓶颈几乎永远不在你假设的位置,务必先测量。
STOP — Do NOT proceed to Phase 3 until:
停止条件——满足以下条件前请勿进入阶段3:
- Profiling tool appropriate to the layer has been used
- Specific bottleneck is identified with data
- Bottleneck accounts for a significant portion of the problem
- 已使用对应层级的合适分析工具
- 已通过数据定位到具体的瓶颈
- 该瓶颈是导致问题的主要原因
Phase 3: OPTIMIZE (Fix the Identified Bottleneck)
阶段3:优化(修复已识别的瓶颈)
Goal: Apply the targeted fix. Change ONE thing at a time.
目标: 实施针对性修复,每次仅改动一项内容。
Optimization Decision Table
优化决策表
| Bottleneck Type | Optimization Approach | Example |
|---|---|---|
| Large bundle | Code splitting, tree shaking, dynamic imports | |
| Slow API response | Caching, query optimization, pagination | Add Redis cache with 5min TTL |
| Slow database query | Add index, optimize query plan, materialized view | |
| Excessive re-renders | Memoization, virtualization, state restructuring | |
| Large images | Compression, lazy loading, responsive images | |
| Slow TTFB | Server-side caching, CDN, edge rendering | Stale-while-revalidate pattern |
| Memory leak | Fix event listener cleanup, weak references | Proper |
| 瓶颈类型 | 优化方案 | 示例 |
|---|---|---|
| 包体积过大 | 代码分割、tree shaking、动态导入 | |
| API响应慢 | 缓存、查询优化、分页 | 新增TTL为5分钟的Redis缓存 |
| 数据库查询慢 | 添加索引、优化查询计划、物化视图 | |
| 过度重渲染 | 记忆化、虚拟化、状态重构 | |
| 大图片 | 压缩、懒加载、响应式图片 | |
| TTFB过长 | 服务端缓存、CDN、边缘渲染 | stale-while-revalidate 模式 |
| 内存泄漏 | 修复事件监听器清理问题、使用弱引用 | 规范的 |
STOP — Do NOT proceed to Phase 4 until:
停止条件——满足以下条件前请勿进入阶段4:
- Only ONE change has been made
- Change directly targets the identified bottleneck
- No unrelated changes were made alongside the optimization
- 仅完成了一项改动
- 改动直接针对已识别的瓶颈
- 优化过程中没有引入无关改动
Phase 4: VERIFY (Measure Again)
阶段4:验证(再次测量)
Goal: Re-run the exact same measurement from Phase 1.
目标: 复用阶段1的完全相同的测量方法重新执行。
Actions
操作步骤
- Run the same profiling/measurement as Phase 1
- Compare results:
- Did the metric improve?
- By how much?
- Did any other metrics regress?
- If improvement is not measurable, REVERT the change.
Optimization that cannot be measured is not optimization.
- 执行和阶段1完全相同的分析/测量操作
- 对比结果:
- 指标是否有所改进?
- 改进幅度是多少?
- 其他指标是否出现退化?
- 如果改进无法量化,回退该改动。
无法量化的优化不能称之为优化。
STOP — Verification complete when:
停止条件——满足以下条件时验证完成:
- Same measurement methodology used as Phase 1
- Improvement is quantified (e.g., "LCP reduced from 3.2s to 2.1s")
- No regressions in other metrics
- If no improvement: change reverted
- 使用了和阶段1完全相同的测量方法
- 改进已被量化(例如 "LCP从3.2s降低到2.1s")
- 其他指标没有出现退化
- 如果没有改进:已回退改动
Caching Strategy Decision Table
缓存策略决策表
| Cache Type | Use When | TTL Guidance | Invalidation |
|---|---|---|---|
| In-memory (LRU) | Single-instance, hot data, computed values | Seconds to minutes | Eviction policy |
| Redis/Memcached | Multi-instance, shared cache, sessions | Minutes to hours | Event-based or TTL |
| CDN | Static assets, public pages, API responses | Hours to days | Deploy-triggered purge |
| Browser | Repeat visits, static resources | Days to months (versioned) | Cache-busting hash |
| 缓存类型 | 适用场景 | TTL建议 | 失效策略 |
|---|---|---|---|
| 内存缓存(LRU) | 单实例场景、热点数据、计算值 | 数秒到数分钟 | 驱逐策略 |
| Redis/Memcached | 多实例场景、共享缓存、会话 | 数分钟到数小时 | 事件触发或TTL过期 |
| CDN | 静态资源、公开页面、API响应 | 数小时到数天 | 部署触发清理 |
| 浏览器缓存 | 重复访问场景、静态资源 | 数天到数月(带版本号) | 缓存哈希戳 |
Cache-Control Headers
Cache-Control 头配置
undefinedundefinedImmutable assets (hashed filenames)
不可变资源(带哈希文件名)
Cache-Control: public, max-age=31536000, immutable
Cache-Control: public, max-age=31536000, immutable
API responses (cacheable but must revalidate)
API响应(可缓存但必须重新验证)
Cache-Control: public, max-age=0, must-revalidate
ETag: "abc123"
Cache-Control: public, max-age=0, must-revalidate
ETag: "abc123"
Private user data
私有用户数据
Cache-Control: private, no-store
Cache-Control: private, no-store
Stale-while-revalidate (fast response + background refresh)
Stale-while-revalidate(快速响应+后台刷新)
Cache-Control: public, max-age=60, stale-while-revalidate=300
---Cache-Control: public, max-age=60, stale-while-revalidate=300
---Bundle Optimization Techniques
包体积优化技术
| Technique | Impact | Implementation |
|---|---|---|
| Route-level code splitting | High | |
| Tree shaking | High | ES modules only, |
| Dynamic imports | Medium | |
| Image optimization | High | next/image, WebP/AVIF, responsive srcset |
| Font optimization | Medium | |
| Dependency replacement | Medium | day.js for moment.js, lodash-es for lodash |
| 技术方案 | 优化效果 | 实现方式 |
|---|---|---|
| 路由级代码分割 | 高 | 每个路由使用 |
| Tree shaking | 高 | 仅使用ES模块,配置 |
| 动态导入 | 中 | 用户触发操作时执行 |
| 图片优化 | 高 | next/image、WebP/AVIF格式、响应式srcset |
| 字体优化 | 中 | |
| 依赖替换 | 中 | 用day.js替代moment.js,用lodash-es替代lodash |
Bundle Analysis Commands
包体积分析命令
bash
undefinedbash
undefinedWebpack
Webpack
npx webpack-bundle-analyzer stats.json
npx webpack-bundle-analyzer stats.json
Vite
Vite
npx vite-bundle-visualizer
npx vite-bundle-visualizer
Next.js
Next.js
ANALYZE=true next build
---ANALYZE=true next build
---Database Query Tuning
数据库查询调优
Index Optimization
索引优化
sql
-- Find missing indexes (PostgreSQL)
SELECT schemaname, tablename, seq_scan, idx_scan
FROM pg_stat_user_tables
WHERE seq_scan > idx_scan
ORDER BY seq_scan DESC;sql
-- 查找缺失的索引(PostgreSQL)
SELECT schemaname, tablename, seq_scan, idx_scan
FROM pg_stat_user_tables
WHERE seq_scan > idx_scan
ORDER BY seq_scan DESC;Index Rules
索引规则
| Rule | Explanation |
|---|---|
| Index WHERE, JOIN, ORDER BY columns | These are the columns the DB searches |
| Equality columns first in composite index | Most selective filtering first |
| Range columns last in composite index | Less selective, applied after equality |
| Remove unused indexes | They slow down writes |
| Use partial indexes for filtered queries | Smaller index, faster lookups |
| 规则 | 说明 |
|---|---|
| 对WHERE、JOIN、ORDER BY涉及的列建索引 | 这些是数据库检索的核心列 |
| 联合索引中等值匹配列放在最前 | 最高筛选优先级的列在前 |
| 联合索引中范围匹配列放在最后 | 筛选优先级较低,在等值匹配后生效 |
| 删除未使用的索引 | 会拖慢写入性能 |
| 为过滤查询使用部分索引 | 索引体积更小,查询速度更快 |
Query Plan Red Flags
查询计划危险信号
| Red Flag in EXPLAIN ANALYZE | Meaning | Fix |
|---|---|---|
| Seq Scan on large table | Full table scan | Add index |
| Nested Loop with many rows | O(n*m) join | Add index or restructure query |
| Sort with high memory | Sorting in memory | Add index matching ORDER BY |
| Actual rows >> estimated rows | Stale statistics | Run ANALYZE |
| Hash Join with large build | Memory-intensive | Ensure join columns are indexed |
| EXPLAIN ANALYZE中的危险信号 | 含义 | 修复方案 |
|---|---|---|
| 大表上的 Seq Scan | 全表扫描 | 添加索引 |
| 大量行的 Nested Loop | 时间复杂度为O(n*m)的关联查询 | 添加索引或重构查询 |
| 高内存消耗的 Sort | 在内存中完成排序 | 添加匹配ORDER BY的索引 |
| 实际行数 >> 预估行数 | 统计信息过时 | 执行ANALYZE命令 |
| 大构造表的 Hash Join | 内存消耗极高 | 确保关联列已建索引 |
Web Vitals Targets
Web Vitals 指标目标
| Metric | Good | Needs Work | Poor |
|---|---|---|---|
| LCP (Largest Contentful Paint) | < 2.5s | 2.5-4s | > 4s |
| INP (Interaction to Next Paint) | < 200ms | 200-500ms | > 500ms |
| CLS (Cumulative Layout Shift) | < 0.1 | 0.1-0.25 | > 0.25 |
| 指标 | 优秀 | 待优化 | 不佳 |
|---|---|---|---|
| LCP(最大内容绘制) | < 2.5s | 2.5-4s | > 4s |
| INP(交互到 next 绘制) | < 200ms | 200-500ms | > 500ms |
| CLS(累计布局偏移) | < 0.1 | 0.1-0.25 | > 0.25 |
Web Vitals Optimization Table
Web Vitals优化表
| Metric | Optimization | Implementation |
|---|---|---|
| LCP | Preload LCP resource | |
| LCP | Inline critical CSS | Extract above-fold CSS inline |
| LCP | Optimize TTFB | CDN, edge rendering, server caching |
| INP | Break long tasks | |
| INP | Debounce input handlers | 100-300ms debounce on expensive handlers |
| INP | Web Workers | Move computation off main thread |
| CLS | Explicit dimensions | Set |
| CLS | Reserve space for dynamic content | Placeholder sizing for ads, embeds |
| CLS | Use transform animations | Avoid layout-triggering properties |
| 指标 | 优化方案 | 实现方式 |
|---|---|---|
| LCP | 预加载LCP资源 | |
| LCP | 内联关键CSS | 提取首屏CSS内联到页面 |
| LCP | 优化TTFB | CDN、边缘渲染、服务端缓存 |
| INP | 拆分长任务 | |
| INP | 输入处理函数防抖 | 耗时的处理函数添加100-300ms防抖 |
| INP | Web Workers | 将计算逻辑移到主线程外 |
| CLS | 显式设置尺寸 | 为图片和视频设置 |
| CLS | 为动态内容预留空间 | 为广告、嵌入内容设置占位符尺寸 |
| CLS | 使用transform动画 | 避免触发布局重排的属性 |
Load Testing
负载测试
Test Types
测试类型
| Type | Users | Duration | Purpose |
|---|---|---|---|
| Smoke | 1-2 | 1 minute | Verify test works |
| Load | Expected traffic | 10-30 min | Normal performance |
| Stress | 2-3x expected | 10-30 min | Find breaking point |
| Soak | Normal load | 2-8 hours | Find memory leaks |
| 类型 | 并发用户数 | 持续时长 | 用途 |
|---|---|---|---|
| 冒烟测试 | 1-2 | 1分钟 | 验证测试逻辑可用 |
| 负载测试 | 预期流量 | 10-30分钟 | 验证正常负载下的性能 |
| 压力测试 | 2-3倍预期流量 | 10-30分钟 | 找到系统崩溃阈值 |
| 耐力测试 | 正常负载 | 2-8小时 | 发现内存泄漏问题 |
Key Metrics
核心指标
- Response time percentiles (p50, p95, p99) — not averages
- Error rate under load
- Throughput (requests per second)
- Resource utilization (CPU, memory, connections)
- 响应时间分位数(p50、p95、p99)——而非平均值
- 负载下的错误率
- 吞吐量(每秒请求数)
- 资源利用率(CPU、内存、连接数)
Anti-Patterns / Common Mistakes
反模式/常见错误
| Anti-Pattern | Why It Is Wrong | Correct Approach |
|---|---|---|
| Optimizing without measuring | You do not know what to fix | MEASURE first, always |
| Premature optimization | Wastes time on non-bottlenecks | Profile to find actual bottleneck |
| Memoizing everything | Adds complexity without proven benefit | Profile first, memoize second |
| Caching without invalidation strategy | Stale data causes bugs | Define invalidation before adding cache |
| Optimizing averages instead of percentiles | Averages hide tail latency | Track p95 and p99 |
| Multiple optimizations at once | Cannot attribute improvement | One change at a time |
| Keeping optimizations that do not measurably help | Dead code and complexity | Revert if no measurable improvement |
| Adding indexes without checking query patterns | Unused indexes slow writes | Check slow query log first |
| 反模式 | 错误原因 | 正确做法 |
|---|---|---|
| 未测量就开始优化 | 不知道真正需要修复的问题 | 永远先测量,再优化 |
| 过早优化 | 浪费时间在非瓶颈点上 | 先分析找到真实瓶颈 |
| 所有内容都加记忆化 | 增加复杂度却没有可验证的收益 | 先分析,再加记忆化 |
| 缓存没有失效策略 | 数据陈旧导致业务bug | 添加缓存前先定义失效规则 |
| 优化平均值而非分位数 | 平均值掩盖了长尾延迟问题 | 跟踪p95和p99指标 |
| 同时进行多项优化 | 无法定位改进的来源 | 每次仅改动一项内容 |
| 保留无法带来可量化改进的优化 | 产生死代码和额外复杂度 | 没有可量化改进就回退 |
| 未检查查询模式就添加索引 | 未使用的索引会拖慢写入性能 | 先查看慢查询日志再建索引 |
Subagent Dispatch Opportunities
子Agent调度机会
| Task Pattern | Dispatch To | When |
|---|---|---|
| Profiling different system layers concurrently | | When analyzing frontend, backend, and database independently |
| Bundle analysis and tree-shaking review | | When frontend bundle size is a concern |
| Database query optimization analysis | | When slow queries are identified across multiple tables |
Follow the skill protocol when dispatching.
dispatching-parallel-agents| 任务模式 | 调度到 | 适用场景 |
|---|---|---|
| 同时分析不同系统层的性能 | | 需要独立分析前端、后端和数据库性能时 |
| 包体积分析和tree shaking审查 | | 前端包体积过大需要优化时 |
| 数据库查询优化分析 | | 多个表都存在慢查询问题时 |
调度时遵循 技能协议。
dispatching-parallel-agentsIntegration Points
集成点
| Skill | Relationship |
|---|---|
| Frontend performance uses bundle and Web Vitals optimization |
| Backend performance uses caching and query tuning |
| Load tests are part of the testing pyramid |
| Review checks for performance regressions |
| Performance issues follow the same investigation methodology |
| Performance targets become acceptance criteria |
| 关联技能 | 关联关系 |
|---|---|
| 前端性能优化包含包体积和Web Vitals优化 |
| 后端性能优化包含缓存和查询调优 |
| 负载测试是测试金字塔的组成部分 |
| 代码评审需要检查性能退化问题 |
| 性能问题遵循相同的排查方法论 |
| 性能目标会成为验收标准 |
Skill Type
技能类型
FLEXIBLE — Adapt the depth of optimization to the project context. The MEASURE-IDENTIFY-OPTIMIZE-VERIFY cycle is mandatory for every optimization. Revert any change that does not produce measurable improvement.
FLEXIBLE ——可根据项目上下文调整优化深度。所有优化都必须遵循MEASURE-IDENTIFY-OPTIMIZE-VERIFY周期。任何无法产生可量化改进的改动都应当回退。