mcpField
P
profile-tests

profile-tests

github.com/editframe测试与质量1969 次安装2 周前更新
代码仓库

关于 profile-tests

这份指南介绍 elements 包中浏览器测试、场景、播放、导出和页面加载的性能分析,帮助开发者定位热点、查看模式并与基线比较。

主要功能

  1. 01分析浏览器测试和场景
  2. 02生成文本或 JSON 报告
  3. 03识别性能热点与模式
  4. 04将分析结果与保存的基线比较
  5. 05分析播放、导出和页面加载

适用场景

  1. 01查找浏览器测试中的 CPU 热点
  2. 02排查运行缓慢的沙盒场景
  3. 03依据基线验证优化效果
  4. 04检查播放或导出性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/editframe/skills --skill profile-tests

安装后在 Claude Code 中输入/profile-tests确认已加载。

详细介绍

性能分析测试和浏览器测试

使用统一的性能分析库对 elements 包测试进行 CPU 性能分析。识别性能瓶颈、生成优化建议并检测反模式。

快速命令

性能分析浏览器测试(简单模式)
# Built-in profiling for all browser tests
./scripts/browsertest --profile

# Profile specific test file
./scripts/browsertest --profile packages/elements/src/preview/renderTimegroupToCanvas.browsertest.ts

# Profile with test pattern
./scripts/browsertest --profile -t "batch capture"
性能分析浏览器测试(详细分析)
# Full analysis with unified profiling library
npx tsx scripts/profile-browsertest.ts \
  packages/elements/src/preview/renderTimegroupToCanvas.browsertest.ts

# Get JSON output for LLM analysis
npx tsx scripts/profile-browsertest.ts \
  packages/elements/src/preview/renderTimegroupToCanvas.browsertest.ts \
  --json

# Focus on specific file
npx tsx scripts/profile-browsertest.ts \
  packages/elements/src/preview/renderTimegroupToCanvas.browsertest.ts \
  --focus renderToImage \
  --json
性能分析场景
# Profile a scenario in sandbox
./scripts/ef profile EFCanvas basic --json

# With pattern detection
./scripts/ef profile EFCanvas basic --json --verbose

# Compare against baseline
./scripts/ef profile EFCanvas basic \
  --baseline .profiles/baseline.cpuprofile \
  --json

性能问题排查工作流

排查测试中的性能问题时:

1. 捕获初始性能分析数据
# For browser tests
npx tsx scripts/profile-browsertest.ts \
  packages/elements/src/preview/renderTimegroupToCanvas.browsertest.ts \
  --json > profile.json

# For scenarios
./scripts/ef profile EFCanvas basic --json > profile.json
2. 分析 JSON 输出

解析性能分析数据以识别:

{
  "hotspots": [
    {
      "rank": 1,
      "functionName": "updateFrame",
      "file": "EFTimegroup.ts",
      "line": 234,
      "selfTimeMs": 45.2,
      "selfTimePct": 31.1,
      "callCount": 234
    }
  ],
  "byFile": [
    { "file": "EFTimegroup.ts", "timeMs": 82.1, "timePct": 56.5 }
  ],
  "recommendations": [
    "• updateFrame called 234 times - consider caching"
  ],
  "patterns": [
    {
      "name": "Hot Loop Detected",
      "severity": "high",
      "suggestion": "Review loop logic..."
    }
  ]
}
3. 确定优化优先级

重点关注:

  • selfTimePct > 15% 的函数(关键瓶颈)
  • callCount > 100 且 selfTimePct > 5% 的函数(缓存机会)
  • timePct > 40% 的文件(架构问题)
  • severity: "high" 的模式
4. 进行更改

根据检测到的模式应用优化。

5. 通过基线对比进行验证
# Save baseline before changes
./scripts/ef profile EFCanvas basic \
  --save .profiles/baseline-$(date +%Y%m%d-%H%M%S).cpuprofile

# After optimization, compare
./scripts/ef profile EFCanvas basic \
  --baseline .profiles/baseline-TIMESTAMP.cpuprofile \
  --json

检查对比输出:

  • selfTimeDiffMs 为负值 = 性能提升 ✅
  • selfTimeDiffMs 为正值 = 性能退化 ⚠️

了解性能分析指标

关键指标
指标含义用途
selfTimeMs函数自身耗时(不包括被调用函数)直接优化目标
selfTimePct占总性能分析时间的百分比确定优先级(>15% = 关键)
callCount函数出现在调用栈中的次数缓存/记忆化决策
hitCount捕获到该函数的性能分析采样次数检测循环(>200 = 紧密循环)
解读模式

统一的性能分析库可检测 8 种常见反模式:

过度操作 DOM → 批量更新 DOM 或使用 DocumentFragment
布局抖动 → 将布局读取与写入分开
热点循环 → 优化循环体或减少迭代次数
千刀万剐式开销 → 为频繁调用的函数添加记忆化
繁重的 JSON 操作 → 使用结构化克隆或减少序列化
频繁计算样式 → 缓存计算后的样式
动画 API 开销 → 缓存动画对象
文件级耗时集中 → 需要进行架构审查

常见优化模式

调用次数高(>100)+ 耗时适中(5-15%)

问题: 函数被频繁调用,但每次开销较小
解决方案: 记忆化或缓存

// Before
function expensiveCalculation(x: number) {
  return /* complex math */;
}

// After
const cache = new Map<number, number>();
function expensiveCalculation(x: number) {
  if (cache.has(x)) return cache.get(x)!;
  const result = /* complex math */;
  cache.set(x, result);
  return result;
}
自身耗时高(>30%)+ 调用次数低(<10)

问题: 单个函数承担了过多工作
解决方案: 降低复杂度或延迟执行工作

// Before
function processAll() {
  // All work done synchronously
  loadData();
  transformData();
  validateData();
  saveData();
}

// After  
function processAll() {
  loadData(); // Only critical work
  queueMicrotask(() => {
    transformData();
    validateData();
    saveData();
  });
}
检测到 DOM 操作模式

问题: 多次更新 DOM 导致重排
解决方案: 批量更新

// Before
for (const item of items) {
  container.appendChild(createItem(item)); // Multiple reflows
}

// After
const fragment = document.createDocumentFragment();
for (const item of items) {
  fragment.appendChild(createItem(item));
}
container.appendChild(fragment); // Single reflow

输出格式

文本输出(便于阅读)
./scripts/ef profile EFCanvas basic

显示:

  • 按自身耗时排序的热点
  • 按文件汇总的耗时
  • 自动生成的建议
  • 检测到的模式(使用 --verbose 时)
JSON 输出(便于大模型/脚本处理)
./scripts/ef profile EFCanvas basic --json

用于程序化分析的结构化数据:

  • 按排名排列并包含指标的热点
  • 文件级汇总
  • 建议数组
  • 模式检测结果
详细模式(增强分析)
./scripts/ef profile EFCanvas basic --json --verbose

还会显示:

  • 调用次数信息
  • 反模式检测
  • 详细建议

专用性能分析工具

分析播放性能
npx tsx scripts/profile-playback.ts \
  --project improv-edit \
  --duration 5000 \
  --json
分析导出性能
npx tsx scripts/profile-export.ts \
  --project design-catalog \
  --json
分析页面加载性能
npx tsx scripts/profile-load.ts \
  --project improv-edit \
  --json

故障排查

“性能分析函数不可用”

  • 确保浏览器由 Playwright 控制(使用 ef open,而非普通浏览器)

“性能分析数据为空”

  • 场景/测试可能执行得太快(<10ms)
  • 尝试运行时间更长的测试,或增加测试复杂度

“数值很大,似乎不合理”

  • 检查时间单位是微秒还是毫秒
  • 统一的性能分析库返回毫秒
  • 旧版接口可能使用微秒

“调用次数似乎不正确”

  • 调用次数是根据调用栈遍历得出的近似值
  • 可改用 hitCount 获取基于采样的频率

最佳实践

  1. 始终保存基线,再进行更改
  2. 关注自身耗时,以直接产生影响(总耗时包含被调用者的耗时)
  3. 从排名前 3 的热点开始,以获得最大影响
  4. 使用 JSON 输出进行程序化分析
  5. 手动分析前先检查模式——它们会指出具体的修复方法
  6. 通过比较更改前后的性能分析结果来验证更改
  7. 留意基线比较中的性能回退

其他资源

  • 完整的性能分析指南:elements/PROFILING.md
  • LLM 专用指南:elements/LLM_PROFILING_GUIDE.md
  • 实现详情:elements/PROFILING_IMPLEMENTATION_SUMMARY.md
  • 库源代码:packages/elements/src/profiling/

评论

支持 Markdown