mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-30 19:09:28 +00:00
Switching to a STREAMING session took ~1.4s to settle while an idle
session settled in ~50ms. The autopsy probe named it: the
FIRST_PAINT_BUDGET -> RENDER_BUDGET backfill runs as a transition, an
interrupted transition restarts from scratch, and stream flushes land
every 33-250ms — so the 300-part backfill re-rendered over and over
(measured: 1374ms settle, 30 commits, Primitive.div x2237 for one switch).
Gate the backfill on the thread being idle. The user lands on the live
tail immediately either way; older turns backfill the moment the run
ends, and 'Show earlier' remains the manual path meanwhile.
Measured on the live app (diag-switch-autopsy, real sessions):
switch to idle session ~35-55ms settled (unchanged)
switch to streaming session 1374ms -> backfill deferred; lands at
the live tail like any other switch
Adds diag-switch-autopsy.mjs (per-switch settle/commits/top-renders) and
live-drive.mjs (status/fps/drag one-liners against the running app).
52 lines
1.8 KiB
JavaScript
52 lines
1.8 KiB
JavaScript
// Session-switch autopsy: click between the two heaviest rows repeatedly,
|
|
// recording per-switch (a) settled ms, (b) React commits, (c) top rendered
|
|
// components — so slow switches name themselves.
|
|
import { attach } from './perf/lib/launch.mjs'
|
|
import { sleep } from './perf/lib/cdp.mjs'
|
|
|
|
const arg = (name, fallback) => {
|
|
const i = process.argv.indexOf(`--${name}`)
|
|
|
|
return i === -1 ? fallback : process.argv[i + 1]
|
|
}
|
|
|
|
const port = Number(arg('port', 9222))
|
|
const ROUNDS = Number(arg('rounds', 8))
|
|
|
|
const { cdp, teardown } = await attach({ port })
|
|
|
|
const SWITCH_ONE = index => `
|
|
(async () => {
|
|
const rows = [...document.querySelectorAll('[data-slot="row-button"]')].filter(el => el.offsetParent)
|
|
if (rows.length < 2) return JSON.stringify({ error: 'rows' })
|
|
const row = rows[${index} % 2]
|
|
const rc = window.__RENDER_COUNTS__
|
|
rc.start()
|
|
const t0 = performance.now()
|
|
row.click()
|
|
let lastMutation = performance.now()
|
|
const mo = new MutationObserver(() => { lastMutation = performance.now() })
|
|
mo.observe(document.body, { childList: true, subtree: true, characterData: true })
|
|
const deadline = performance.now() + 4000
|
|
while (performance.now() < deadline) {
|
|
await new Promise(r => requestAnimationFrame(r))
|
|
if (performance.now() - lastMutation > 150) break
|
|
}
|
|
mo.disconnect()
|
|
rc.stop()
|
|
const settled = Math.round(performance.now() - t0 - 150)
|
|
const report = rc.report(6).map(r => r.name + ':' + r.renders + '(' + Math.round(r.totalMs) + 'ms)')
|
|
return JSON.stringify({ label: (row.textContent ?? '').slice(0, 24), settled, commits: rc.commits(), top: report })
|
|
})()
|
|
`
|
|
|
|
try {
|
|
await cdp.send('Runtime.enable')
|
|
|
|
for (let i = 0; i < ROUNDS; i++) {
|
|
console.log(await cdp.eval(SWITCH_ONE(i)))
|
|
await sleep(400)
|
|
}
|
|
} finally {
|
|
teardown?.()
|
|
}
|