Repository navigation
perf(ui): repaint only the Mission Control card that moves - #72
Merged
Merged
Conversation
Every working card's travelling current asked the pulse clock for frames on behalf of the whole board, so with four agents working the board was notified about 30 times a second (41 with the header speedster) and each time re-rendered every card from a fresh clone of the board. - Each card is its own cached view (the MiniSpinner pattern). The board hands a card new props only when they differ (compared in place, no clone), so a pulse frame re-renders that card alone and its neighbours reuse last frame's layout and paint. - The header speedster is a cached sprite view. Its frame steps no longer notify the board, and it follows the Dock's rules: asleep and a settled alert hold still, working moods cap at 4 fps on battery or in Low Power Mode, and nothing moves while no window is visible. - The board is held as Arc<Board> instead of being cloned per render. The working current stays on the 30 Hz clock: it is continuous motion, and at 15 Hz its bright core would jump about 12 px per frame. Waiting and settling cards already run at 15 Hz. Measured in a gpui test (4 working + 2 finished cards, one second of frames): board notifies 41/s -> 0, card renders 246/s (6 per board render) -> 120/s (4 x 30, finished cards 0), speedster frames on its own 11/s view. gpui still re-runs the board's render on each frame (ancestors of a dirty view re-render), now as a thin pass over cached cards. GODSPEED_FRAME_STATS=1 logs the mission-control and mission-control-card cadence.
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.
Mission Control re-rendered the whole board on every animation frame. Each working card's travelling current asked the shared pulse clock for frames on the board's behalf, so the whole view, every card included, re-rendered at the 30 Hz pulse. The header speedster added its own 8 to 12 Hz on top, and every render started from a fresh clone of the
Board.Changes
MiniSpinner/ zoomie-mascot pattern). The board passes a card new props only when they differ, comparing in place so nothing is cloned. A pulse frame re-renders only that card. The cards around it reuse last frame's layout and paint.Speedster::plan):AppVisibility).Arc<Board>, so a render no longer clones it.GODSPEED_FRAME_STATS=1now also logsmission-controlandmission-control-cardrender cadence, next to the existingshellandsidebarcounters.Measured
This is a gpui test with 4 working cards and 2 finished cards. It counts one second of pulse frames, and the test platform draws a window whenever it is dirty. The "before" numbers come from the same harness run on
origin/mainwith a render counter added.MissionControl) notificationsBoardclonesThe test
a_pulse_frame_repaints_only_the_working_cardsasserts that no pulse or speedster frame notifies the board and that finished cards never re-render. The testthe_header_speedster_holds_still_when_nobody_can_see_itcovers the visibility rule.Notes
renderon each frame. When a view is notified, gpui marks its ancestors dirty, so a card's pulse re-runs the parent's render. That pass is now thin. It builds the header, the group headers and one cached placeholder per card, and it rebuilds the board at most once a second for the elapsed labels, as before. The number of window frames is unchanged: 30 Hz while a card works, plus the speedster's steps.MENU_BLUR * 1.5) is a scene primitive, so every window frame recomputes it. This PR leaves the frame count and the blur unchanged.list/uniform_listwould mean flattening the device and project groups into rows, and reworking focus-reveal scrolling and the edge fade. That is not worth the risk at this size.Check by hand
Aand Enter on cards should behave as before.GODSPEED_FRAME_STATS=1. The logs showview render cadencewithview=mission-control-card.