Compare commits

...

3 Commits

Author SHA1 Message Date
Christian Byrne
348b464d3c fix: include heapDeltaBytes in perf-report baseline comparison
Add heapDeltaBytes to REPORTED_METRICS so heap regressions appear
in baseline diff tables and CI logs alongside taskDurationMs, style
recalcs, and layouts. Update formatValue to use formatBytes for
human-readable heap delta display.

Addresses review feedback:
https://github.com/Comfy-Org/ComfyUI_frontend/pull/10495#discussion_r2985278220
2026-03-25 17:46:50 -07:00
bymyself
a1a79d6916 fix: enable Vue renderer in fast-pan memory pressure test 2026-03-25 11:41:45 -07:00
bymyself
c9d6a81e19 test: add perf test for fast-pan memory pressure 2026-03-24 18:40:57 -07:00
2 changed files with 58 additions and 2 deletions

View File

@@ -300,6 +300,58 @@ test.describe('Performance', { tag: ['@perf'] }, () => {
})
})
test('fast pan memory pressure', async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('large-graph-workflow')
await comfyPage.vueNodes.waitForNodes()
const canvas = comfyPage.canvas
const box = await canvas.boundingBox()
if (!box) throw new Error('Canvas bounding box not available')
await comfyPage.perf.startMeasuring()
// Rapidly pan back and forth across the large graph (245 nodes).
// Each pan pass triggers reactive node instrumentation as nodes
// enter/leave the viewport. Without idempotent instrumentation,
// each pass leaks ComputedRefImpl, Link, Dep, and EventListener
// objects (~198K ComputedRefImpl and 1.5M Link objects observed
// in the original heap snapshot analysis).
const centerX = box.x + box.width / 2
const centerY = box.y + box.height / 2
for (let pass = 0; pass < 5; pass++) {
await comfyPage.page.mouse.move(centerX, centerY)
await comfyPage.page.mouse.down({ button: 'middle' })
for (let i = 0; i < 60; i++) {
await comfyPage.page.mouse.move(
centerX + i * 8,
centerY + (i % 2 === 0 ? i * 3 : -i * 3)
)
await comfyPage.nextFrame()
}
await comfyPage.page.mouse.up({ button: 'middle' })
// Return to center for next pass
await comfyPage.page.mouse.move(centerX, centerY)
await comfyPage.page.mouse.down({ button: 'middle' })
for (let i = 0; i < 60; i++) {
await comfyPage.page.mouse.move(
centerX - i * 8,
centerY - (i % 2 === 0 ? i * 3 : -i * 3)
)
await comfyPage.nextFrame()
}
await comfyPage.page.mouse.up({ button: 'middle' })
}
const m = await comfyPage.perf.stopMeasuring('fast-pan-memory')
recordMeasurement(m)
console.log(
`Fast pan memory: ${(m.heapDeltaBytes / 1024 / 1024).toFixed(1)}MB heap delta, ${m.eventListeners} event listeners, ${m.taskDurationMs.toFixed(1)}ms task`
)
})
test('workflow execution', async ({ comfyPage }) => {
// Uses lightweight PrimitiveString → PreviewAny workflow (no GPU needed)
await comfyPage.workflow.loadWorkflow('execution/partial_execution')

View File

@@ -50,6 +50,7 @@ type MetricKey =
| 'eventListeners'
| 'totalBlockingTimeMs'
| 'frameDurationMs'
| 'heapDeltaBytes'
const REPORTED_METRICS: { key: MetricKey; label: string; unit: string }[] = [
{ key: 'styleRecalcs', label: 'style recalcs', unit: '' },
{ key: 'layouts', label: 'layouts', unit: '' },
@@ -58,7 +59,8 @@ const REPORTED_METRICS: { key: MetricKey; label: string; unit: string }[] = [
{ key: 'scriptDurationMs', label: 'script duration', unit: 'ms' },
{ key: 'eventListeners', label: 'event listeners', unit: '' },
{ key: 'totalBlockingTimeMs', label: 'TBT', unit: 'ms' },
{ key: 'frameDurationMs', label: 'frame duration', unit: 'ms' }
{ key: 'frameDurationMs', label: 'frame duration', unit: 'ms' },
{ key: 'heapDeltaBytes', label: 'heap delta', unit: 'bytes' }
]
function groupByName(
@@ -134,7 +136,9 @@ function computeCV(stats: MetricStats): number {
}
function formatValue(value: number, unit: string): string {
return unit === 'ms' ? `${value.toFixed(0)}ms` : `${value.toFixed(0)}`
if (unit === 'ms') return `${value.toFixed(0)}ms`
if (unit === 'bytes') return formatBytes(value)
return `${value.toFixed(0)}`
}
function formatDelta(pct: number | null): string {