0017. retainContextWhenHidden on four pages: those whose live state cannot be saved, or is costly to rebuild

Status: Accepted (2026-10-02), as decided for open question 1 of the webviews plan on 2026-10-01. Supersedes 0006.

Context

0006 kept retainContextWhenHidden only for the Dashboard’s query editor and the Task Board’s drag. Phase 6 then found two more pages that 0006 did not weigh. The search page carries the same query editor as the Dashboard, so a half-built query would be lost on hide. The Notes Graph runs a simulation that would restart on every reveal: its nodes jump and settle again, and a large graph spends CPU each time. Its whole-workspace graph also takes 1.4 s to build on 5,000 notes, and its message is about 40 MB.

A page that is not kept running is drawn again when it is shown. Since Phase 6, a page that reads inert state has its HTML set again when it is hidden, carrying the last snapshot it was sent (Q2). What the reader chose in it comes back from setState.

Decision

Four pages keep retainContextWhenHidden:

Page Why it is kept
Dashboard Its query editor holds a half-built query, its caret, and its builder rows, and Home may be mid-arrangement. None of these can be saved quickly at the moment of a hide.
Search page The same query editor, half built in its box.
Task Board A drag in progress (pointer capture, the dragged card’s linger) and the same query editor.
Notes Graph Its simulation would restart on every reveal, its nodes jumping and settling again. The graph it would need again is the costliest snapshot Deckard builds.

Six pages drop it, and keep what the reader chose in them with setState:

Page What it keeps, and why that is enough
Stats { showAllOrphans, showUsedOnce, pairsAsTable, scrollY }. Its snapshot is redrawn from the last one sent (Q2).
Help { guide?, scrollY, drawn }. Its body is static and host-built, and a guide page is asked for again when it is shown.
Calendar page { layout, scrollY }. Its month is cheap enough to build into its HTML (Q3).
Calendar view Nothing, as before. Its month is in its HTML.
Related Notes The reader’s choices and its scroll (row 24b of the persisted-formats inventory). It is drawn again from the last state it posted, and a reveal ranks at most once: not at all when nothing changed while it was hidden.
Related Notes debug page Nothing. It runs no script and draws one entry’s evidence whole in its HTML, so it only comes back at the top with its calculations folded.

The stale refresh on onDidChangeViewState stays everywhere, kept or not.

Consequences

Alternatives considered