Keep the view across a tab switch
Perspective's auto-pause is on by default, and pausing deletes the view: AutoPauseState::apply() fires on the viewer's own IntersectionObserver and on the document's visibilitychange, and set_pause(true) does view_sub.take().delete(). Coming back is therefore not a redraw but restore_and_render() -- a fresh view and a fresh traversal of the whole grain -- which is the multi-second chug on every tab switch, and takes any per-node expansion with it. Nothing updates the table while the tab is hidden; every operation is driven from this page. So the pause bought nothing and cost a rebuild. Also drops a comment that still described the old set_depth re-apply on refocus, whose machinery is long gone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a028cdb79a
commit
d14036d1b5
15
CLAUDE.md
15
CLAUDE.md
@ -272,6 +272,21 @@ gone:
|
||||
|
||||
`split_full` is still *read* on load, for layouts saved under the old scheme.
|
||||
|
||||
### Auto-pause is off
|
||||
|
||||
`<perspective-viewer>` auto-pauses by default: an `IntersectionObserver` on
|
||||
itself plus the document's `visibilitychange` drive `AutoPauseState::apply()`,
|
||||
and pausing **deletes the view** (`session.set_pause(true)` →
|
||||
`view_sub.take().delete()`). Returning to the tab is therefore not a redraw but
|
||||
`restore_and_render()` — a fresh view and a fresh traversal of the whole grain,
|
||||
which on a large one is a multi-second chug on every tab switch, and takes any
|
||||
per-node expansion with it.
|
||||
|
||||
`initViewer()` calls `viewer.setAutoPause(false)` right after `viewer.load()`.
|
||||
Nothing updates the table while the tab is hidden — every operation is driven
|
||||
from this page — so the pause bought nothing and cost a rebuild. The view is now
|
||||
held while the tab is backgrounded.
|
||||
|
||||
### Still not solved: per-node expansion
|
||||
|
||||
Expanding one specific branch is view state with no config representation, and
|
||||
|
||||
@ -259,12 +259,6 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
// the current selection, readable from event handlers that were registered once
|
||||
const slicesRef = useRef([])
|
||||
|
||||
// Perspective's ROLLUP view contains every level of the hierarchy; view.set_depth()
|
||||
// is the only thing hiding the deeper ones, and it lives on the view rather than in
|
||||
// the saved config. The viewer rebuilds its view when it redraws — which its
|
||||
// Intersection/ResizeObserver triggers when you switch back to the tab — and the
|
||||
// fresh view has no depth set, so the whole tree appears expanded. Re-apply the
|
||||
// depth we last set once the redraw has settled.
|
||||
// perspective-click fires as a CustomEvent with no modifier state of its own,
|
||||
// and carries no cell coordinates either, so record both from the mousedown that
|
||||
// precedes it. The grid lives in a shadow root, so the real target is the head of
|
||||
@ -822,6 +816,22 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio
|
||||
// that occurs when viewer.load(worker) + restore({ table: name }) can't resolve
|
||||
// the named table in time.
|
||||
await viewer.load(tableRef.current)
|
||||
|
||||
// Auto-pause is on by default, and pausing *deletes the view*:
|
||||
// AutoPauseState::apply() fires on visibilitychange and on the viewer's own
|
||||
// IntersectionObserver, and set_pause(true) does
|
||||
// `view_sub.take().delete()`. Coming back is therefore not a redraw but
|
||||
// `restore_and_render()` -- a fresh view, a fresh traversal of the whole
|
||||
// grain -- which is the multi-second chug on every tab switch, and why any
|
||||
// per-node expansion is gone when you return.
|
||||
//
|
||||
// Nothing updates the table while the tab is hidden (operations are driven
|
||||
// from this page), so the pause buys nothing here and costs a rebuild.
|
||||
// Guarded: it is a method on the custom element, absent on older builds.
|
||||
try { if (viewer.setAutoPause) await viewer.setAutoPause(false) } catch (err) {
|
||||
console.error('[setAutoPause]', err)
|
||||
}
|
||||
|
||||
viewer.setAttribute('theme', dark ? 'Pro Dark' : 'Pro Light')
|
||||
if (!hideSplitTotal()) setTimeout(hideSplitTotal, 400)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user