Skip to content

Fix delayed autofocus cleanup so hidden thoughts are shimmed - #4969

Merged
raineorshine merged 2 commits into
cybersemics:mainfrom
marcus-pousette:fix/delayed-autofocus-virtualization
Aug 17, 2026
Merged

Fix delayed autofocus cleanup so hidden thoughts are shimmed#4969
raineorshine merged 2 commits into
cybersemics:mainfrom
marcus-pousette:fix/delayed-autofocus-virtualization

Conversation

@marcus-pousette

Copy link
Copy Markdown
Contributor

Addresses #2399.

Related to the iOS Safari deep-navigation report in #4325.

Problem

useDelayedAutofocus sets an unmounted ref in its effect cleanup. React runs that cleanup before every autofocus-driven rerun, not only on unmount, so the ref becomes permanently true after the first transition. Subsequent delayed updates are discarded.

During progressive deep navigation, thoughts that move to hide therefore never become lightweight fixed-height shims. Their full editor trees remain mounted after leaving the visible layout, causing DOM and WebContent memory to grow with depth.

Solution

  • Cancel the pending autofocus timer in effect cleanup instead of latching an unmounted flag.
  • Add hook coverage for the delayed update and cancellation on unmount.
  • Add a mounted-layout regression test that verifies distant hide thoughts are unmounted, hide-parent thoughts remain mounted for the existing fade-in behavior, and navigating back remounts the ancestor.

This is deliberately narrower than #2582: it does not change Subthought/VirtualThought layout, opacity, or hide-parent behavior that was implicated in the Safari regression in #2650.

Physical-device results

Measured on an iPhone 13 mini running iOS 26.6 in Mobile Safari with the same 150-level Hello1Hello150 fixture and a 75-step slow-scroll run lasting about 65 seconds. WebContent process metrics were sampled at roughly 1 Hz.

Metric Before After Change
Average WebContent CPU 50.8% 41.0% -19.2%
Peak WebContent CPU 70.4% 49.8% -29.2%
Average physical footprint 966.2 MB 535.3 MB -44.6%
Peak physical footprint 1,024 MB 561 MB -45.2%
Mounted editables at depth 150 150 4 -97.3%
DOM nodes at depth 150 4,566 1,937 -57.6%

The before/after builds were based on the same TreeCRDT integration revision because that is the reported surface; the affected hook and layout code are identical to upstream main. An unpatched upstream-main control showed the same retention behavior and averaged 926.6 MB during the scroll.

These are directional measurements from one physical-device run per build, not a formal benchmark. Neither build hard-reloaded on iOS 26.6; the original hard reload was reported on iOS 26.5.2, so confirmation on the affected device is still needed. Navigating back 20 levels after the patched run did not reproduce the y-position drift from #2650.

Verification

  • Focused hook/component tests: 4 passed. On the pre-fix implementation, the delayed hook value remains false and the distant a thought remains mounted.
  • yarn lint:tsc
  • yarn lint:src
  • yarn build
  • Physical iPhone deep navigation, slow scrolling, and 20-level back navigation

Co-Authored-By: Codex GPT-5 (unknown context) <noreply@openai.com>
@marcus-pousette

Copy link
Copy Markdown
Contributor Author

Pupeeteer seem to be red, investigating

Co-Authored-By: Codex GPT-5 (unknown context) <noreply@openai.com>

@raineorshine raineorshine left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, thank you

@raineorshine
raineorshine merged commit cf4a256 into cybersemics:main Aug 17, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants