关于 profile-tests
这份指南介绍 elements 包中浏览器测试、场景、播放、导出和页面加载的性能分析,帮助开发者定位热点、查看模式并与基线比较。
主要功能
- 01分析浏览器测试和场景
- 02生成文本或 JSON 报告
- 03识别性能热点与模式
- 04将分析结果与保存的基线比较
- 05分析播放、导出和页面加载
适用场景
- 01查找浏览器测试中的 CPU 热点
- 02排查运行缓慢的沙盒场景
- 03依据基线验证优化效果
- 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获取基于采样的频率
最佳实践
- 始终保存基线,再进行更改
- 关注自身耗时,以直接产生影响(总耗时包含被调用者的耗时)
- 从排名前 3 的热点开始,以获得最大影响
- 使用 JSON 输出进行程序化分析
- 手动分析前先检查模式——它们会指出具体的修复方法
- 通过比较更改前后的性能分析结果来验证更改
- 留意基线比较中的性能回退
其他资源
- 完整的性能分析指南:
elements/PROFILING.md - LLM 专用指南:
elements/LLM_PROFILING_GUIDE.md - 实现详情:
elements/PROFILING_IMPLEMENTATION_SUMMARY.md - 库源代码:
packages/elements/src/profiling/
评论
支持 Markdown