Skip to content

Reduce chat composer rerenders during streaming#2888

Draft
cursor[bot] wants to merge 5 commits into
mainfrom
cursor/component-performance-optimization-eac8
Draft

Reduce chat composer rerenders during streaming#2888
cursor[bot] wants to merge 5 commits into
mainfrom
cursor/component-performance-optimization-eac8

Conversation

@cursor
Copy link
Copy Markdown
Contributor

@cursor cursor Bot commented May 31, 2026

What Changed

  • Stabilized ChatComposer inputs so streaming thread message updates do not pass the full changing activeThread object into the memoized composer.
  • Reused stable empty thread metadata for activities/proposed plans.
  • Added stable event-callback wrappers for composer actions and error handling.
  • Added React Scan before/after recordings:
    • artifacts/react-scan/before-chat-composer-rerender.webm
    • artifacts/react-scan/after-chat-composer-rerender.webm

Why

React Doctor and manual hot-path review identified ChatView/ChatComposer as a high-churn surface during streaming. React Scan confirmed the composer region was highlighted during assistant token updates even though the composer was idle. The after recording shows the streaming timeline still updates while the composer region is no longer highlighted.

UI Changes

No intended visual UI changes. Included before/after React Scan screen recordings for the interaction/performance behavior.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Verification:

  • bun fmt
  • bun lint (0 errors, existing warnings)
  • bun typecheck
  • bunx react-doctor --json --full --no-score apps/web
  • bunx react-doctor --json --diff main --no-score apps/web
  • React Scan before/after recordings with a seeded streaming-thread fixture
Open in Web View Automation 

Note

Reduce ChatComposer rerenders during streaming by stabilizing props

  • Introduces useStableModelSelection to return a referentially stable ModelSelection ref that only updates when the value materially changes, preventing unnecessary rerenders.
  • Wraps onSend, onInterrupt, and other handler callbacks in useEventCallback to give them stable identities across renders.
  • Refactors ChatComposer props to accept activeThreadProviderInstanceId directly instead of the full Thread object, reducing the surface area that triggers rerenders.
  • Replaces missing or empty activities/proposed plans with stable EMPTY_* constants to avoid new object references on each render.

Macroscope summarized de26297.

cursoragent and others added 5 commits May 31, 2026 16:13
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
Co-authored-by: Julius Marminge <juliusmarminge@users.noreply.github.com>
@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 May 31, 2026
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