Skip to content

perf(web-shell): lazy-load chat & activity feeds to fix DM-view lag#41

Merged
andrew-jon-p7a merged 1 commit into
mainfrom
feat/thread-optimizations
May 16, 2026
Merged

perf(web-shell): lazy-load chat & activity feeds to fix DM-view lag#41
andrew-jon-p7a merged 1 commit into
mainfrom
feat/thread-optimizations

Conversation

@andrew-jon-p7a
Copy link
Copy Markdown
Contributor

@andrew-jon-p7a andrew-jon-p7a commented May 16, 2026

Entering a DM mounted the entire transcript plus the fully-expanded
activity timeline, and the activity pipeline (clip → filter →
buildThread) was recomputed from scratch on every arriving WS row —
quadratic in turn count because hashMessage re-serialized each
exchange's full prefix.

  • Add useWindowedList: render only a trailing window of each feed, grown a page at a time, reset on context switch.
  • Add thread-history: per-thread lazy history paging (hydrateThread + loadOlderThreadMessages). Closes a gap where DM views only showed whatever the global backfill happened to include.
  • messages.ts: appendMessages fast-path concat (no full re-sort) for in-order arrivals; add prependMessages for paging.
  • AgentTimeline: memoize the clip/filter/buildThread pipeline and objectivesSeen; WeakMap-cache hashMessage so each payload is serialized once per page; window TimelineBody.
  • Transcript: windowed render + scroll-anchored "load older" bar; hydrate the thread's first page on open.

First paint is now bounded (~80 message rows / ~60 thread items) and
the per-WS-frame cost drops from a full quadratic pipeline to a memo
hit plus a window slice.

Related

Checklist

  • All commits are signed off (git commit -s) — the DCO bot will confirm
  • pnpm lint is clean
  • pnpm typecheck is clean
  • pnpm test passes
  • Docs/README updated if user-facing behavior changed

  Entering a DM mounted the entire transcript plus the fully-expanded
  activity timeline, and the activity pipeline (clip → filter →
  buildThread) was recomputed from scratch on every arriving WS row —
  quadratic in turn count because hashMessage re-serialized each
  exchange's full prefix.

  - Add useWindowedList: render only a trailing window of each feed,
    grown a page at a time, reset on context switch.
  - Add thread-history: per-thread lazy history paging (hydrateThread +
    loadOlderThreadMessages). Closes a gap where DM views only showed
    whatever the global backfill happened to include.
  - messages.ts: appendMessages fast-path concat (no full re-sort) for
    in-order arrivals; add prependMessages for paging.
  - AgentTimeline: memoize the clip/filter/buildThread pipeline and
    objectivesSeen; WeakMap-cache hashMessage so each payload is
    serialized once per page; window TimelineBody.
  - Transcript: windowed render + scroll-anchored "load older" bar;
    hydrate the thread's first page on open.

  First paint is now bounded (~80 message rows / ~60 thread items) and
  the per-WS-frame cost drops from a full quadratic pipeline to a memo
  hit plus a window slice.

Signed-off-by: Andrew Jon Przybilla <andrew@przy.email>
@andrew-jon-p7a andrew-jon-p7a merged commit f805298 into main May 16, 2026
1 check passed
@andrew-jon-p7a andrew-jon-p7a deleted the feat/thread-optimizations branch May 24, 2026 14:41
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