Repository navigation
perf(companion): resting robots draw a fraction of the frames - #45
Merged
Merged
Conversation
…breaths in sub-pixel steps
Merged
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.
Cuts the frames the compositor draws for a robot at rest, without a change anyone would see. Follow-up to #43.
What I found first
A trace of Chrome's compositor (
DrawFrame,BeginFrame) corrected the starting assumption. An endless animation that is still 93 % of its cycle (the 5 s blink) draws almost nothing: Chrome skips frames whose values did not change. It only keeps the compositor waking up on every vsync. What draws on every frame of the display is the continuous breathing: the box'sbreathe(scale 1.012 x 1.03), the Jelly's, Bubble's float, Capsule's rock, the Retro's scanline.What changed
src/lib/companion/stepped.ts: slow loops whose motion is tiny are sampledSTEP_HZ(20) times a second along their own eased curve and held between samples (steps(1, end)). Rhythm and amplitude stay the same. A loop qualifies only if no step moves any corner of the robot by more than 0.25 px at 128 px, the desktop's 64 px on a screen scaled to 200 %.stepped.test.tschecks that guard for every loop. Stepped: the box's breath (3, 4 and 6 s), the Jelly's breath (4 and 6 s) and the Capsule's doze. Not stepped because they move more: Capsule's rock (11 px), Bubble's float (6 px), the Retro scanline, hops, work motions and the sleepingz.src/lib/companion/beats.ts: one timer for every robot starts the gestures that are still most of their cycle. Each runs only while it shows: the box blink (5 s),RobotFace's blink (4.6 s), the Retro antenna wiggle (4.2 s) and screen flicker (5 s). The rhythm is jittered by ±20 % around the same period, and robots start out of phase. Nothing starts whiledata-dormant, under reduced motion, or for an element off screen. The one-shot keyframes are the moving slice of the old loops, rescaled, with the same easing.onscreen(same file): oneIntersectionObservermarks robots scrolled or clipped out of view withdata-offscreen, andbots.csspauses their animations.will-changeon the layers that blink or wiggle. Without it, every gesture created and dropped a layer and repainted it: the first try took the gallery from 1 to 14 ms/s of main thread.scripts/perf-probe.ts --frames: traces the compositor per pose and counts frames drawn, compositor wakes and display swaps per second. New poses: one robot of each family awake and asleep (?view=mascots&family=<f>&mood=idle&shapes=1), and the pill and desktop for each family (skin=). The gallery gained themood=andshapes=parameters it needs.Measurements
Production build (
perf.vite.config.ts), headless Chrome at 60 Hz on the AMD iGPU, 10 s per pose, before and after back to back. At 60 Hz a smoothly animating page draws about 60 frames a second; on a 240 Hz screen it would draw 240. A stepped breath draws about 20 at any refresh rate.closed,open-threads,desktop-*) have agents working in the fake core, so their robots hum, scan and pulse continuously. They stay near the display rate before and after. Their single runs swing between 27 and 60. Three repeat runs ofclosedandopen-threadsgave 51.6 to 57.1 on both builds.zdrifts 13 px over 3 s, too far to step.Not verified
Checks
bun run check: 0 errors, 0 warnings (308 files)bun run test: 68 files, 495 tests passed (new:stepped.test.ts,beats.test.ts)bun run test:scripts: 0 fail;bun run check:manifest: acceptedCaptures
Not attached: this machine has no image host. Before and after captures were opened and compared, and they match apart from animation phases: the full gallery (
?view=mascots) and the open island for each family (pose=open&tab=threads&calm=1&skin=<family>). They are listed in the result file.