Skip to content

fix(app): anchor virtual timeline to bottom#4

Merged
Hona merged 2 commits into
perf/session-timeline-virtuafrom
fix/virtual-timeline-anchor-1778643000
May 13, 2026
Merged

fix(app): anchor virtual timeline to bottom#4
Hona merged 2 commits into
perf/session-timeline-virtuafrom
fix/virtual-timeline-anchor-1778643000

Conversation

@Hona
Copy link
Copy Markdown
Owner

@Hona Hona commented May 13, 2026

Summary

  • Anchor the virtual timeline to the last row on initial mount when we are in normal latest/follow-bottom mode.
  • Keep hash/deep-link/pending-message/user-scrolled paths out of the anchor path.
  • Use virtua's itemSize hint only when no exact row-key cache exists, so cold loads avoid the default ~40px estimate.

Measurement setup

  • Base: latest origin/perf/session-timeline-virtua at 5c0d9ed030 after cache PR merge.
  • URL/origin: http://127.0.0.1:3002.
  • Target static session: fix: Flicker on load / ses_1e62fb38dffegWEV7SJWQKxJXZ.
  • Review panel closed/unmounted: reviewCounts: [0, 0].
  • Heavy settings verified on both runs: reasoning summaries, shell parts expanded, edit parts expanded.
  • Measurement source: Chrome DevTools rAF DOM sampling + MutationObserver + Chrome performance traces.

Revisit with cache: baseline vs PR

This measures the first candidate change. The PR path uses its own generated cache snapshot, so total scrollHeight is not treated as an apples-to-apples truth metric here; the useful signal is whether a rendered frame exposes the temporary top/zero-scroll state.

Metric Baseline cache branch This PR
First sampled root 47ms 111ms
First sampled root scrollTop 0 17239
First sampled root bottom-aligned no yes
rAF samples with session root at scrollTop=0 1 0
First bottom-aligned sample 88ms 111ms
Height-change samples 12126 only 18237 only
Trace virtua-followup-static-baseline-trace.json.json.gz virtua-followup-static-anchor-trace.json.json.gz

Cold load, no cache: baseline vs PR

This measures the second candidate change (itemSize fallback) plus the anchor.

Metric Baseline cache branch This PR
Initial total estimate 2600px 3900px
First sampled root scrollTop 0 2902
rAF samples with session root at scrollTop=0 1 0
Height correction sequence 2600 -> 9969 -> 11488 -> 12126 3900 -> 8444
First bottom-aligned sample 807ms 113ms
Trace virtua-followup-cold-baseline-trace.json.json.gz virtua-followup-cold-final-trace.json.json.gz

Validation

  • packages/app: bun typecheck
  • push hook: bun turbo typecheck

Notes

  • itemSize=60 is an official virtua size hint and is only active without a matching cache. It is still an estimate by design; exact row-key cache remains preferred when available.
  • I did not add min-height reservations or custom measurement logic.

Copilot AI review requested due to automatic review settings May 13, 2026 03:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the session message timeline virtualization behavior to avoid an initial “top/zero-scroll” flicker by anchoring the virtualized list to the bottom on initial mount (only in normal follow-bottom scenarios), and improves cold-load estimation by supplying a better virtua itemSize hint when no row-key cache is available.

Changes:

  • Add a bottom-anchor path in MessageTimeline that scrolls to the last row once per session key when shouldAnchorBottom() allows it.
  • Thread a shouldAnchorBottom() predicate from session.tsx to keep deep-link/hash/pending-message/user-scrolled cases out of the anchor path.
  • Provide virtua an itemSize fallback (60px) only when no virtualizer cache exists.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/app/src/pages/session/message-timeline.tsx Adds one-time bottom anchoring logic per session and uses an itemSize hint only when cache is absent.
packages/app/src/pages/session.tsx Supplies shouldAnchorBottom() based on URL hash, deep-link state, pending message, and user-scrolled state; adds useLocation() usage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Hona Hona merged commit fba26d1 into perf/session-timeline-virtua May 13, 2026
2 of 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.

2 participants