Repository navigation
perf(studio): an idle editor stops waking the GPU four times a second - #6109
Merged
Merged
Conversation
The overlay frame loop's safety-net poll requested one animation frame every 250 ms for as long as the editor stayed open. Each request restarts the display's vsync for a few frames, so a paused, untouched editor kept the GPU process waking ~65 times a second. The poll now doubles its wait after each idle frame up to 4 s, resets to 250 ms on any wake, and stops while the page is hidden (visibilitychange already wakes it). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Contributor
Edit accuracy: accurate 271 (base branch 271), smooth 154 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Contributor
There was a problem hiding this comment.
Verdict: APPROVE · 0 blocker · 0 important · 1 nit · head 3a61eba5
While the page is hidden, nothing is armed, and it re-arms correctly: visibilitychange fires at document and bubbles to the capture listener on window. A pending rAF simply waits until the page is visible again. Every wake resets the backoff. CI is green on this head (the red PR captures run was superseded by a passing one).
- nit: the module header (
overlayFrameLoop.ts:16-17) still says a missed wake costs "a quarter second of staleness". After long idle it is now up to 4 s (MAX_IDLE_POLL_MS), as the PR body says.
— Genesis (Claude)
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.
What
The overlay frame loop's safety-net poll (
IDLE_POLL_MS,overlayFrameLoop.ts) requested one animation frame every 250 ms for as long as an editor stayed open. Each frame request restarts the display's vsync (a freshCVDisplayLinkon macOS) for a few frames, so a paused, untouched editor kept the GPU process waking ~65 times a second, the main idle battery cost in HyperFrames Desktop with a project open.Now the poll:
MAX_IDLE_POLL_MS), and resets to 250 ms on any wake. A missed wake is likeliest right after activity (a CSS transition no event reports), which is when the poll is still fast.document.hidden;visibilitychangeis already a wake source.No visible change
The overlays track the same geometry on the same wake sources; only how often an idle, untouched editor polls changes. Under 20 source lines, no .tsx/.css/.html.
Measured
HyperFrames Desktop at
origin/main(studio 0.8.186), paused project, 20 s ofapp.getAppMetrics()per run, M4 Pro. Baseline vs this change applied to the same 0.8.186 dist (two runs):Home and playback are unchanged (other sources dominate there). Earlier isolation on the same build: removing only this loop's idle rAFs took a paused project's GPU wakeups from 85/s to 20/s. Method and charts: https://www.heygenverse.com/a/efa8d156-d36a-4c3e-80c7-c9b1a4f07dcf
Tests
Two new cases in
overlayFrameLoop.test.ts: the poll backs off and comes back fast after a wake, and no poll is armed while hidden. Both fail onmain(47 polls in 12 s idle, where ≤4 is expected; 31 polls while hidden, where ≤1 is expected). All 15 pass with the change.Not exercised
No Studio walk in a browser; the measurement is Desktop's embedded Studio. A missed wake source now costs up to 4 s of overlay staleness after long idle instead of 250 ms; none was seen, but the wake sources were not exhaustively audited.
🤖 Generated with Claude Code