perf(core): stop rescanning stable content on scroll-only frames - #24
Merged
Merged
Conversation
pi-tui rebuilds its render cache every frame, so a wheel scroll re-rendered the whole content tree — and the frame clamp re-ran visibleWidth over every transcript row (~20-60ms/frame past the 512-entry width cache). Make the render path identity-stable so scroll frames only diff the viewport: - FrameClampedContainer clamps each child independently, keyed on the row array it returned; a stable transcript is never rescanned, and a changed sibling only pays for its own rows. - TranscriptModelComponent returns a fresh array per live update instead of mutating a reused frame buffer (same-identity mutation is now invisible to the clamp cache). - LocalActivityRegion / StableSlotHost / GutterComponent / BannerComponent reuse their row arrays while children and width are unchanged. - SurfaceManager memoizes layout() and linearLayout() per viewport until registry, user-state, focus, activation, or collapse flags change. - The dock's surface budget reuses the lanes' own rendered row counts via measureRows() instead of rendering panes a second time. Verified: verify:full, check:pack, smoke:pty, smoke:pty:mouse. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FrameClampedContainerre-ranvisibleWidthover every transcript row (~20-60ms/frame once past the 512-entry width cache), blowing the 16ms frame budget and producing the stutter + visible repaint artifacts.FrameClampedContainernow clamps each child independently, keyed on the row array it returned. A stable transcript is never rescanned; a changed sibling pays only for its own rows. Frame-relative overflow indexes are preserved.LocalActivityRegion/StableSlotHost/GutterComponent/BannerComponentreuse their row arrays while children and width are unchanged;TranscriptModelComponentreturns a fresh array per live update instead of mutating a reused frame buffer (same-identity mutation is now invisible to the clamp).SurfaceManager.layout()/linearLayout()memoize per viewport until registry, user-state, focus, activation, or collapse flags change;setCollapsedinvalidates on flag flips so collapse hysteresis stays identical to fresh computation. The dock's surface budget reuses lane row counts viameasureRows()instead of rendering panes a second time.doRender()on the real composition drops from ~20-60ms to <1ms on synthetic 1.5k-4k-row transcripts; remaining per-frame cost is pi-tui's viewport diff write.Test plan
pnpm run verify:changed— related specs, 100% coverage on touched filespnpm run verify:full— 3378 tests, typecheck, lint, build, happy smokepnpm run check:pack— all 3 tarballs cleanpnpm run smoke:pty(40x24 narrow PTY session) andpnpm run smoke:pty:mouse(wheel path)dsh --profile mayfly-scroll-perf: long-transcript wheel/PgUp scrolling, live streaming at tail, manual scroll away +Endfollow, narrow-width collapse,/new+ session-switch lifecycleGenerated with Devin