Frame-boundary scheduling that keeps working in hidden tabs.
The update pipeline yields to the render loop between serialized view
updates (queue-next.ts) and on refinement cancellation hand-off
(SceneLoader.scheduleGSplatsRefinement's onCancel) so at least one
frame paints before the next update. Plain requestAnimationFrame is the
right primitive while the tab is visible — but browsers suspend rAF when
document.hidden, so with bare rAF a pending view-state queued in a
background tab stalls until the tab is foregrounded (e.g. a programmatic
scrub driven while the user watches another window never progresses).
Policy:
rAF available and the document visible → schedule via rAF, plus a
shadow setTimeout fallback so a tab hidden AFTER scheduling still
progresses (first source to fire wins; the other is a guarded no-op).
rAF available but the document already hidden → setTimeout(cb, 0)
(there is no frame to wait for).
Frame-boundary scheduling that keeps working in hidden tabs.
The update pipeline yields to the render loop between serialized view updates (
queue-next.ts) and on refinement cancellation hand-off (SceneLoader.scheduleGSplatsRefinement'sonCancel) so at least one frame paints before the next update. PlainrequestAnimationFrameis the right primitive while the tab is visible — but browsers suspend rAF whendocument.hidden, so with bare rAF a pending view-state queued in a background tab stalls until the tab is foregrounded (e.g. a programmatic scrub driven while the user watches another window never progresses).Policy:
setTimeoutfallback so a tab hidden AFTER scheduling still progresses (first source to fire wins; the other is a guarded no-op).setTimeout(cb, 0)(there is no frame to wait for).