perf(tui): instrument scroll fast-path decline reasons
Adds scrollFastPathStats counters to render-node-to-output.ts: captures every time a ScrollBox's DECSTBM scroll hint is generated, records whether the fast path took it (blit+shift from prevScreen) or declined, and why. Exposed through hermes-ink's public exports and snapshotted on every FrameEvent so the profiler harness can correlate decline reasons with the actual patch/renderer cost per frame. This is pure observation — no behaviour change. Preparing for the virtual-history rewrite: the hypothesis was that our topSpacer/ bottomSpacer scheme disqualifies every scroll via heightDelta mismatch, but the data shows the fast path is actually taken on most scrolls (19/23 over a 6s PageUp hold through 1100 messages) — the remaining steady-state renderer cost is Yoga tree traversal, not the per-frame full redraw I initially suspected. Declines that do happen correlate with React commits that changed the mounted range mid-scroll (heightDelta=±3 to ±35). Those are the rarer cases the virtualization rewrite still needs to address. No test diffs — instrumentation-only. Build verified: `tsc --noEmit` plus the full `npm run build` compiler post-pass pass cleanly.
This commit is contained in:
18
ui-tui/src/types/hermes-ink.d.ts
vendored
18
ui-tui/src/types/hermes-ink.d.ts
vendored
@@ -101,6 +101,24 @@ declare module '@hermes/ink' {
|
||||
export const TextInput: React.ComponentType<any>
|
||||
export const stringWidth: (s: string) => number
|
||||
|
||||
export type ScrollFastPathStats = {
|
||||
captured: number
|
||||
taken: number
|
||||
declined: {
|
||||
noPrevScreen: number
|
||||
heightDeltaMismatch: number
|
||||
noHint: number
|
||||
other: number
|
||||
}
|
||||
lastDeclineReason?: string
|
||||
lastHeightDelta?: number
|
||||
lastHintDelta?: number
|
||||
lastScrollHeight?: number
|
||||
lastPrevHeight?: number
|
||||
}
|
||||
export const scrollFastPathStats: ScrollFastPathStats
|
||||
export function resetScrollFastPathStats(): void
|
||||
|
||||
export function render(node: React.ReactNode, options?: NodeJS.WriteStream | RenderOptions): Instance
|
||||
|
||||
export function useApp(): { readonly exit: (error?: Error) => void }
|
||||
|
||||
Reference in New Issue
Block a user