You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On a long session the scrollbar thumb compresses and repositions while the reader scrolls up, and scrollHeight keeps changing without any content arriving. This is the symptom #828 fixed in July: never-rendered content occupies an estimated height until Chromium gets around to laying it out, so each upward step inflates the document and scroll anchoring compensates — the top keeps receding.
Since #5170 the Renderer also decides from this geometry when to fill an edge and what to trim (packages/ui/src/use-chat-scroll.ts, the two-screen fill and six-screen trim bands). Estimated heights that later grow make those bands fire early or late. That is a performance problem now, not a correctness one — the anchored window refuses anything it cannot splice — but it is the same root cause.
Added turn-size-warmup.ts: a chunked, bottom-up idle walk that forces each Turn through one rendering opportunity so the browser records its size. Measured: a 24-Turn session mounted at scrollHeight 14640 vs 31872 real, 51 anchor-corrected steps to reach the top; after warm-up, exact geometry and monotonic scrollTop.
Deleted turn-size-warmup.test.ts (8 cases) and e2e/scroll-geometry.spec.ts (565 lines) as "low-value" — the only tests that would have failed on the steps below.
Bounded rendering within oversized Turns with content-visibility line-block chunks (packages/ui/src/styles.css:744). The estimate is now per chunk inside a Turn, with nothing walking chunks to measure them.
Result: the browser's remembered-size mechanism is once again the only thing turning estimates into measurements, and it only runs for what scrolls into view — exactly the situation #828 measured.
Open it at the tail, then scroll to the top with the wheel or the scrollbar.
Watch scrollHeight (or the thumb): it grows step by step during the ascent; the top recedes.
The deleted e2e/scroll-geometry.spec.ts (git show 2f5c75be0^:apps/desktop/e2e/scroll-geometry.spec.ts) asserted constant height and monotonic scrollTop for this gesture. Restoring it is the regression; it should fail on main today.
Expected
Geometry that does not change under the reader when no content changed. Either bring the idle warm-up back for whatever now carries the estimate (line-block chunks after #4259), or seed chunk heights from measurement the way #2224 proposed for Turns. The regression that guards it must come back with the fix; #2462 deleting it is how the next three PRs got through.
Not in scope
The Renderer-owned window and its fill/trim bands (#5163 / #5170). They consume this geometry; they do not produce it.
What happened
On a long session the scrollbar thumb compresses and repositions while the reader scrolls up, and
scrollHeightkeeps changing without any content arriving. This is the symptom #828 fixed in July: never-rendered content occupies an estimated height until Chromium gets around to laying it out, so each upward step inflates the document and scroll anchoring compensates — the top keeps receding.Since #5170 the Renderer also decides from this geometry when to fill an edge and what to trim (
packages/ui/src/use-chat-scroll.ts, the two-screen fill and six-screen trim bands). Estimated heights that later grow make those bands fire early or late. That is a performance problem now, not a correctness one — the anchored window refuses anything it cannot splice — but it is the same root cause.The chain
8a47301a5turn-size-warmup.ts: a chunked, bottom-up idle walk that forces each Turn through one rendering opportunity so the browser records its size. Measured: a 24-Turn session mounted atscrollHeight14640 vs 31872 real, 51 anchor-corrected steps to reach the top; after warm-up, exact geometry and monotonicscrollTop.2f5c75be0turn-size-warmup.test.ts(8 cases) ande2e/scroll-geometry.spec.ts(565 lines) as "low-value" — the only tests that would have failed on the steps below.6b8e3db26turn-size-warmup.tsandturn-size-index.ts, replaced by a row virtualizer with spacers. Geometry was now the virtualizer's estimate.c33617fd8d2d9f9060content-visibilityline-block chunks (packages/ui/src/styles.css:744). The estimate is now per chunk inside a Turn, with nothing walking chunks to measure them.Result: the browser's remembered-size mechanism is once again the only thing turning estimates into measurements, and it only runs for what scrolls into view — exactly the situation #828 measured.
How to reproduce
scrollHeight(or the thumb): it grows step by step during the ascent; the top recedes.The deleted
e2e/scroll-geometry.spec.ts(git show 2f5c75be0^:apps/desktop/e2e/scroll-geometry.spec.ts) asserted constant height and monotonicscrollTopfor this gesture. Restoring it is the regression; it should fail onmaintoday.Expected
Geometry that does not change under the reader when no content changed. Either bring the idle warm-up back for whatever now carries the estimate (line-block chunks after #4259), or seed chunk heights from measurement the way #2224 proposed for Turns. The regression that guards it must come back with the fix; #2462 deleting it is how the next three PRs got through.
Not in scope
The Renderer-owned window and its fill/trim bands (#5163 / #5170). They consume this geometry; they do not produce it.