Skip to content

fix(thread): a trim's scrollTop clamp no longer unsticks the transcript (#1475) - #1491

Merged
currentbits merged 3 commits into
mainfrom
coder/deep-dive-transcript-window-stops-trimmi-adb0e3
Oct 6, 2026
Merged

currentbits merged 3 commits into
mainfrom
coder/deep-dive-transcript-window-stops-trimmi-adb0e3

Conversation

@currentbits

Copy link
Copy Markdown
Owner

Part of #1475 (deep dive). During the renderer-heap investigation, in about 2 of 10 soaks the transcript window never trimmed again, as if #1482 weren't there. It's a real app bug; root cause and numbers are in docs/perf/2026-10-06-window-trim.md.

Root cause: the window's own trim unpins the view.

  1. A streamed push takes the window over its character budget, so the oldest entry unmounts and the body gets about 13k px shorter.
  2. The next layout clamps scrollTop to the new height, and that clamp's scroll event is dispatched a frame later.
  3. Before it fires, another push grows the tail by a few lines, so the event sees a distance of 97–156 px. That's past STICK_BOTTOM_PX (80), so onBodyScroll reads it as the user scrolling up.
  4. Once unstuck, the window stops trimming and the view stops following the stream until the user scrolls.

Logs ruled out the #607 pins, the #1489 fill-in and the ResizeObserver pins.

Fix: after a trim while stuck, onBodyScroll ignores scroll events for two animation frames, the window in which the clamp's event can arrive. There's no layout read, so #1489's guarantee of zero layout reads per streaming push still holds. Trade-off: a real scroll-up that starts inside those two frames loses only its first event; the next one unpins as usual.

Reproduction (dev server, headless Chromium, real 3.3 MB thread, 30 short streams per run, varied push interval, CPU throttle, viewport and mid-stream switches):

Runs that lost the pin
Before 9 of 24
After 0 of 24

Verified independently, on main merged with this branch

  • typecheck exits 0 and vite build passes.
  • test:renderer passes 2753 of 2753.
  • The new regression test (it plays the frames in order: trim, clamp, growth, scroll event) fails on main.

🤖 Generated with Claude Code

Willem and others added 3 commits October 6, 2026 12:14
…-switch-frame-8d0baa' and 'origin/coder/perf-h-heap-renderer-heap-growth-3944b5' into coder/deep-dive-transcript-window-stops-trimmi-adb0e3
…pt (#1475)

Trimming the tail window's head makes the browser clamp scrollTop, and the
clamp's scroll event can land after the next streamed push grew the tail
past STICK_BOTTOM_PX. onBodyScroll read that as the user scrolling up, so
the window stopped trimming for the rest of the session. Ignore scrolls for
the two frames a trim's clamp can take to dispatch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-06T12:20:00.550210Z 2aa4351 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@currentbits
currentbits merged commit da26b30 into main Oct 6, 2026
6 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.

1 participant