mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 18:01:20 +08:00
9549e038c4
* perf(studio): run the editor overlays on one parkable frame loop The composition rect, the selection and hover boxes, the off-canvas indicators and the snap guides each owned an animation-frame loop that re-armed unconditionally. On a paused, untouched editor that is four callbacks per frame reading layout, and the snap-guide loop writes style on every one of them, so the compositor kept committing 55 frames a second with nothing moving. None of the four has a clock of its own; each only changes when something observable happens. They now share one loop that runs at full rate for a moment after a pointer, key, wheel, scroll, resize or visibility change, after a preview message reporting a frame the overlays have not drawn, or after a mutation inside the preview document, and otherwise polls four times a second so a wake source nobody thought of costs a quarter second of staleness rather than a frozen overlay. The frame comparison on preview messages is load-bearing rather than an optimisation: the paused preview posts an unchanged status message every 80 ms so any listener can confirm its position, and treating that as news held the overlays at 60 fps for the life of the tab. * fix(studio): one overlay's throw must not stop the other four The shared frame loop re-armed after running its subscribers, so a subscriber that threw took down the loop and its idle-poll safety net permanently. The four loops it replaced each re-armed first, which kept that failure to the one overlay that caused it. It now re-arms before running anything and isolates each subscriber, rethrowing out of band so the error still reaches the page's error reporting. The wake also sat outside the recognised-message check, so postMessage traffic from an extension, devtools or any other embed on the page held the overlays awake for 400ms at a time. Only the preview's own messages wake it now, and a repeated paused status post still does not. useMotionPathData had the same unconditional loop and is live whenever a keyframed element is selected; it joins the shared one. * fix(studio): wake the overlays only for the preview