Skip to content

perf(web): reduce minimap work during streaming and scrolling - #9771

Open
t3dotgg wants to merge 1 commit into
mainfrom
t3code/perf-web-minimap-work
Open

perf(web): reduce minimap work during streaming and scrolling#9771
t3dotgg wants to merge 1 commit into
mainfrom
t3code/perf-web-minimap-work

Conversation

@t3dotgg

@t3dotgg t3dotgg commented Sep 4, 2026

Copy link
Copy Markdown
Member

Streaming rebuilt full minimap previews for every loaded turn. Scrolling rewrote every marker's visibility attribute, even when nothing changed.

The minimap now reuses previews by immutable message identity and skips unchanged marker writes. Its cache keeps only the latest projection, so unused completed replies do not retain extra preview strings. Preview text, row indexes, geometry, and navigation stay unchanged.

Checks

  • All 241 focused tests and web typecheck passed. Lint has no new warnings.
  • The Node source proof reduced a 10-turn update from 0.266 ms to 0.017 ms. A 1,000-turn stress case fell from 29.74 ms to 0.26 ms.
  • Repeating unchanged geometry for 1,000 markers produced zero attribute writes instead of 100,000 across 100 scroll events.
  • Parity, ref recycling, old-snapshot collection, and retained-history cache checks passed.

Small cold cases added about 0.002 ms or improved. The 1,000-turn cold stress case added 0.23 to 1.2 ms across runs. These are source measurements, not browser frame times. No browser or device run was used.

Created with GPT-6 Astra (preview) in Codex.


Note

Low Risk
UI-only performance refactor in the timeline minimap with behavior-preserving tests; no auth, data, or API changes.

Overview
Reduces chat timeline minimap cost during streaming and scroll by caching preview text and skipping redundant DOM updates.

Minimap item building moves from MessagesTimeline.tsx into createTimelineMinimapProjector: a stable projector caches compact user/assistant preview strings keyed by ChatMessage object identity, evicts previews not in the latest projection, and still updates rowIndex when rows reorder. Scroll handling delegates to updateTimelineMinimapMarkers, which sets each strip’s data-in-view only when visibility actually changes (including remounted/recycled refs).

The component keeps one projector instance via useState(createTimelineMinimapProjector) instead of recomputing all previews on every row change. New unit tests cover marker write counts, ref recycling, cache reuse, and parity when turns reorder or supersede earlier replies.

Reviewed by Cursor Bugbot for commit 1e9eca8. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Cache minimap previews and skip redundant marker writes in MessagesTimeline

  • Extracts minimap projection and marker-update logic from MessagesTimeline.tsx into MessagesTimeline.logic.ts
  • createTimelineMinimapProjector caches preview strings by ChatMessage object identity for only the latest projection, scans rows backward to pair each user row with its first assistant row, and returns null for blank previews
  • updateTimelineMinimapMarkers resolves the visible interval from scroll state, computes row intersections using finite row positions, and writes dataset only when the marker's visible state actually changes
  • Risk: resolveTimelineRowTop and resolveTimelineRowHeight return false when row positions are non-finite; marker visibility falls back to false in that case

Macroscope summarized 1e9eca8.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 4, 2026
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.8 KiB 13.6 KiB −167 B (−1.2%) 15.1 KiB
Codex Thread snapshot wire 7.0 KiB 7.0 KiB −6 B (−0.1%) 7.3 KiB
Codex Live turn WebSocket wire 6.7 KiB 6.6 KiB −161 B (−2.3%) 7.8 KiB
Codex Live turn WebSocket decoded 58.5 KiB 57.1 KiB −1.4 KiB (−2.4%) 66.4 KiB
Codex Live turn messages 10 10 0 (0.0%) 21
Claude Total thread wire 13.7 KiB 13.6 KiB −194 B (−1.4%) 15.1 KiB
Claude Thread snapshot wire 7.0 KiB 7.0 KiB −1 B (−0.0%) 7.3 KiB
Claude Live turn WebSocket wire 6.7 KiB 6.5 KiB −193 B (−2.8%) 7.8 KiB
Claude Live turn WebSocket decoded 59.3 KiB 57.8 KiB −1.5 KiB (−2.5%) 66.4 KiB
Claude Live turn messages 10 9 −1 (−10.0%) 21

Baseline: 8e056a0 · PR result: 1e9eca8 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.8 KiB
  • Claude decoded thread snapshot: 114.5 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 1e9eca8

Macroscope's review found this PR approvable — This is a localized, behavior-preserving minimap performance refactor that caches immutable previews and avoids redundant marker DOM writes. Focused tests cover streaming updates, row reordering, cache eviction, and recycled references, with no API, schema, security, billing, or deployment changes.

You can add or adjust custom eligibility rules. Learn more.

@t3dotgg t3dotgg mentioned this pull request Sep 4, 2026
66 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant