feat: virtualize session sidebar list#1669
feat: virtualize session sidebar list#1669Michaelyklam wants to merge 1 commit intonesquena:masterfrom
Conversation
Initial review — session sidebar virtualization (issue #500 first slice)Pulled the branch into an isolated worktree against What I checked:
Looks well-bounded and matches the conservative scope you outlined (sidebar only, message-list virtualization deferred to #734). Queued for full maintainer review. |
|
Closed by the v0.51.1 release in PR #1681 (merged at e23ba59). Massive thanks @Michaelyklam — this is now 19 merged PRs across the v0.50.292–v0.51.1 release window, an extraordinary contribution rate. Each PR was per-claim-vs-diff verified against your description and every security-relevant code path checked under independent review (Opus advisor, 6/6 questions clean). Your Live on production: https://github.com/nesquena/hermes-webui/releases/tag/v0.51.1 🚀 |
…esquena#1669 follow-up PR nesquena#1669 added DOM virtualization to renderSessionListFromCache() with two issues for lists below the virtualization threshold (≤80 rows): 1. The unconditional scroll listener triggered renderSessionListFromCache() on every rAF, rebuilding the entire list DOM on every scroll event. 2. After each rebuild, scrollTop was only restored when virtualWindow.virtualized was true (i.e. total > 80). For lists ≤ 80 rows, scrollTop dropped to 0 on every scroll event, producing a 'scroll keeps jumping back' feel. Fix: - Always restore scrollTop after re-render when listScrollTopBeforeRender > 0 (regardless of virtualized flag). - Short-circuit _scheduleSessionVirtualizedRender when total <= SESSION_VIRTUAL_THRESHOLD_ROWS (saves wasteful rebuild on small lists). Live verified on a 56-session sidebar: scrollTop holds across animation frames. 3 regression tests pin the fix shape.
… hotfix CHANGELOG.md: full v0.51.2 entry covering 3 PRs + sidebar scroll hotfix ROADMAP.md: bump version + test count to 4457 TESTING.md: bump version + test count to 4457 Independent review: Opus advisor on stage-299 diff (1336 LOC). 6/6 verification questions verified clean. Verdict: SHIP. 0 MUST-FIX, 2 SHOULD-FIX absorbed in-release (bounded WIKI walk + URL scheme guard).
Thinking Path
What Changed
renderSessionListFromCache()now builds the fresh filtered/grouped session set, renders only the current visible row window plus buffer, and insertsaria-hiddenspacers inside date groups to preserve scroll height.Refs #500.
Why It Matters
Verification
node --check static/sessions.js/home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_issue500_session_list_virtualization.py tests/test_session_lineage_collapse.py tests/test_sidebar_first_turn_visibility.py tests/test_session_batch_select.py tests/test_login_locale.py tests/test_media_inline.py -q→ 73 passedgit diff --check.session-itemrows for 1000 sessions; activeSynthetic session 450visible; spinner/streaming state preservedSynthetic session 788session 99narrowed to 11 matching rows with no stale virtual windowpytest tests/ -qwas attempted twice. Both runs progressed through the suite but failed in pre-existing/integration test-server/session-state cases unrelated to this static sidebar change (examples:127.0.0.1:24158connection refused intest_issue1144_session_time_sync.py, and several old session persistence tests returning 404). The directly failing integration files reran cleanly in isolation on a fresh port:tests/test_login_locale.py tests/test_media_inline.py→ 42 passed.Risks / Follow-ups
Model Used
gpt-5.5