About profile-tests
A guide to profiling browser tests, scenarios, playback, exports, and page loads in the elements package. It helps developers find performance hotspots, review detected patterns, and compare profiles with saved baselines.
Key features
- 01Profile browser tests and scenarios
- 02Generate text or JSON reports
- 03Identify hotspots and performance patterns
- 04Compare profiles with saved baselines
- 05Profile playback, exports, and page loads
Use cases
- 01Find CPU hotspots in a browser test
- 02Investigate slow sandbox scenarios
- 03Validate an optimization against a baseline
- 04Inspect playback or export performance
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ editframe/ skills --skill profile-testsAfter installing, type/profile-testsin Claude Code to confirm it loaded.
Details
From the project READMEProfiling Tests and Browser Tests
CPU profiling for elements package tests using the unified profiling library. Identifies performance bottlenecks, generates optimization recommendations, and detects anti-patterns.
Quick Commands
Profile Browser Tests (Simple)
# 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"
Profile Browser Tests (Detailed Analysis)
# 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 Scenarios
# 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
Performance Investigation Workflow
When investigating performance issues in tests:
1. Capture Initial Profile
# 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. Analyze JSON Output
Parse the profile to identify:
{
"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. Prioritize Optimizations
Focus on:
- Functions with
selfTimePct > 15%(critical bottlenecks) - Functions with
callCount > 100andselfTimePct > 5%(caching opportunities) - Files with
timePct > 40%(architectural issues) - Patterns with
severity: "high"
4. Make Changes
Apply optimizations based on patterns detected.
5. Validate with Baseline Comparison
# 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
Check comparison output:
- Negative
selfTimeDiffMs= improvement ✅ - Positive
selfTimeDiffMs= regression ⚠️
Understanding Profile Metrics
Key Metrics
| Metric | Meaning | Use For |
|---|---|---|
selfTimeMs | Time in function itself (excluding callees) | Direct optimization target |
selfTimePct | Percentage of total profile time | Prioritization (>15% = critical) |
callCount | Times function appears in call stacks | Caching/memoization decisions |
hitCount | Profile samples that caught function | Loop detection (>200 = tight loop) |
Interpreting Patterns
The unified profiling library detects 8 common anti-patterns:
Excessive DOM Manipulation → Batch DOM updates or use DocumentFragment Layout Thrashing → Separate layout reads from writes Hot Loop → Optimize loop body or reduce iterations Death by a Thousand Cuts → Add memoization for frequently-called functions Heavy JSON Operations → Use structured cloning or reduce serialization Frequent Style Computation → Cache computed styles Animation API Overhead → Cache animation objects File-Level Concentration → Architectural review needed
Common Optimization Patterns
High Call Count (>100) + Moderate Time (5-15%)
Problem: Function called frequently with small individual cost Solution: Memoization or caching
// 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;
}
High Self Time (>30%) + Low Call Count (<10)
Problem: Single function doing too much work Solution: Reduce complexity or defer work
// Before
function processAll() {
// All work done synchronously
loadData();
transformData();
validateData();
saveData();
}
// After
function processAll() {
loadData(); // Only critical work
queueMicrotask(() => {
transformData();
validateData();
saveData();
});
}
DOM Manipulation Pattern Detected
Problem: Multiple DOM updates causing reflows Solution: Batch updates
// 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
Output Formats
Text Output (Human-Readable)
./scripts/ef profile EFCanvas basic
Shows:
- Top hotspots by self time
- Time aggregated by file
- Automated recommendations
- Detected patterns (with --verbose)
JSON Output (LLM/Script-Friendly)
./scripts/ef profile EFCanvas basic --json
Structured data for programmatic analysis:
- Ranked hotspots with metrics
- File-level aggregations
- Recommendations array
- Pattern detection results
Verbose Mode (Enhanced Analysis)
./scripts/ef profile EFCanvas basic --json --verbose
Adds:
- Call count information
- Anti-pattern detection
- Detailed suggestions
Specialized Profiling Tools
Profile Playback Performance
npx tsx scripts/profile-playback.ts \
--project improv-edit \
--duration 5000 \
--json
Profile Export Performance
npx tsx scripts/profile-export.ts \
--project design-catalog \
--json
Profile Page Load
npx tsx scripts/profile-load.ts \
--project improv-edit \
--json
Troubleshooting
"Profiling functions not available"
- Ensure browser is controlled by Playwright (use
ef open, not regular browser)
"Profile data is empty"
- Scenario/test may execute too quickly (<10ms)
- Try longer-running tests or increase test complexity
"High numbers don't make sense"
- Check if times are in microseconds vs milliseconds
- Unified library returns milliseconds
- Legacy interfaces may use microseconds
"Call counts seem wrong"
- Call count is approximate based on call stack traversal
- Use
hitCountfor sampling-based frequency instead
Best Practices
- Always save baselines before making changes
- Focus on self time for direct impact (total time includes callees)
- Start with top 3 hotspots for biggest impact
- Use JSON output for programmatic analysis
- Check patterns before manual analysis - they suggest specific fixes
- Validate changes by comparing before/after profiles
- Watch for regressions in baseline comparisons
Additional Resources
- Full profiling guide:
elements/PROFILING.md - LLM-specific guide:
elements/LLM_PROFILING_GUIDE.md - Implementation details:
elements/PROFILING_IMPLEMENTATION_SUMMARY.md - Library source:
packages/elements/src/profiling/