Repository navigation
perf(studio): the layer walk skips clips the runtime hid, so scrubbing a long film stays smooth - #6416
Conversation
…g a long film stays smooth The off-canvas indicators (always mounted) and the Layers panel rebuild their layer list every 100 ms while a scrub mutates the preview, and each rebuild read the computed style of every element of every scene, on screen or not. The runtime already hides everything inside a clip its visibility pass hid, so those subtrees hold no layer: the walk now skips a clip marked data-hf-clip-hidden with an inline visibility of hidden. The marker constant moves to studio-preview-mark so the runtime and Studio share one owner.
Edit accuracy: accurate 271 (base branch 271), smooth 149 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head aa22718
blocker: the required Studio and player captures check fails on this head. The body has no ## Before/## After section and no ## No visible change section (scripts/check-pr-captures.mjs). This change qualifies for ## No visible change: 13 non-test lines and no .tsx/.css/.html. It is also accurate. Before this PR, isInspectableLayerElement already dropped a runtime-hidden clip and its contents, because their computed visibility is hidden, the clip through its inline style and its contents through the always-installed [data-hf-clip-hidden][data-hf-clip-hidden] * rule. The early return only skips the style reads. So the line "A hidden scene's elements no longer appear in them" describes no change. This is a body-only fix and the head stays the same.
I found no problem in the code. Every other workflow on this head is green, and domEditingLayers.test.ts passes locally (26/26).
|
Measured in the real Desktop app, before and after this change (the app is the only consumer that matters for the scrub target): a 23-minute film of 276,460 elements, a quiet Mac, three 6 s drags of the seek knob with a CPU profile of each.
In the warm profile the layer walk went from about 65% of the sweep to about 45% (the selector index and |
What
Scrubbing a long film in Studio no longer slows down as the film gets longer. While the playhead moves, the editor's layer list skips the scenes the runtime has hidden, so each update costs what is on screen, not the whole document.
Why
Two consumers rebuild the layer list from
collectDomEditLayerItemswhile a scrub mutates the preview:useOffCanvasIndicators), which are mounted whenever the DOM edit overlay is, and rebuild at most every 100 ms on any DOM mutation;Each rebuild visited every element of every scene and called
isInspectableLayerElementon it, which reads its computed style. On a film with 230 scenes of 600 elements that is about 276k style reads per rebuild, almost all of them in scenes that are not on screen.The runtime already hides everything inside a clip its visibility pass hid: it marks the clip
data-hf-clip-hidden, sets its inlinevisibility: hidden, and a stylesheet rule hides its contents (packages/core/src/runtime/timedClipHide.ts). Nothing inside such a clip can be a layer, so the walk can stop there.How
isClipHiddenByRuntime(el)in@hyperframes/core/studio-preview-mark: the clip has the mark and an inlinevisibilityofhidden. Both are required: older shader builds reveal a clip through its inline style only and leave the mark, and such a clip is on screen.collectDomEditLayerItemsreturns early on such a clip.CLIP_HIDDEN_ATTRmoves tostudio-preview-markso the runtime and Studio read one constant;clipReveal.tsre-exports it, so runtime imports are unchanged.What changes in output
None. This is Studio editor code only; render and snapshot are untouched. The layer list and the off-canvas indicators list the same items as before:
isInspectableLayerElementalready dropped everything inside a hidden clip, because its computed visibility is hidden. The early return only skips reading those styles.Test plan
Unit tests added/updated
Manual testing performed
Documentation updated (if applicable)
Comments follow CONTRIBUTING.md "Comments": they say why, not what, and a bug fix says what the code must do and how to reproduce the bug
domEditingLayers.test.ts, "collectDomEditLayerItems and clips the runtime hid":packages/studiosrc/components/editor: 155 files, 1,974 tests pass.packages/coretimedClipHideandclipRevealtests pass.No visible change
13 changed non-test lines, no
.tsx,.cssor.html. The Layers panel and the off-canvas indicators show the same items; only the time spent finding them drops.Why under 100 lines: Miguel's asap P0 for the next Desktop build. One early return in one walk, plus the predicate next to the mark it reads; it shares nothing with any other open change.