Skip to content

UI becomes unresponsive during long tasks due to inefficient state updates #6513

@hannesrudolph

Description

@hannesrudolph

App Version: v3.25.0 (latest)

API Provider: Not Applicable / Other

Model Used: N/A

🔁 Steps to Reproduce:

  1. Open Roo Code extension in VS Code
  2. Start a long-running task (30+ minutes) that generates many messages
  3. Observe that after ~1000 messages, the UI starts to slow down
  4. Continue the task - the UI eventually becomes completely unresponsive ("grey screen")
  5. If multiple VS Code windows are open with Roo Code, ALL instances grey out simultaneously

💥 Outcome Summary:
Expected the UI to remain responsive during long tasks, but got a grey/unresponsive screen across all extension instances due to exponential performance degradation.

📄 Relevant Logs or Errors (Optional):
No error logs - this is a performance issue caused by architectural design.

🔍 Comprehensive Issue Scoping

Root Cause / Implementation Target

The performance issue is caused by the postStateToWebview() method sending the entire conversation history on every state update. As tasks generate more messages, each update becomes exponentially larger, eventually overwhelming the webview's JavaScript thread.

Affected Components

  • Primary Files:

    • src/core/webview/ClineProvider.ts (lines 1312-1320, 1430-1642): Contains postStateToWebview() and getStateToPostToWebview() methods
    • src/core/task/Task.ts (lines 544-545, 1443-1444, 1701-1702): Calls postStateToWebview() after message updates
    • src/extension.ts (line 79): CloudService callback triggers state updates across all instances
  • Secondary Impact:

    • webview-ui/src/context/ExtensionStateContext.tsx: Receives and processes the massive state updates
    • All VS Code windows running the extension (due to CloudService singleton)

Current Implementation Analysis

The function at line 1550 in ClineProvider.ts sends ALL messages by including:

clineMessages: this.getCurrentCline()?.clineMessages || []

This results in O(n²) data transfer as the conversation grows.

Proposed Implementation

Step 1: Implement Incremental Message Updates

  • File: src/core/webview/ClineProvider.ts
  • Changes: Add new method postIncrementalUpdate() that only sends new/changed messages
  • Rationale: Reduces data transfer from O(n²) to O(1) per update

Step 2: Separate Full State vs Updates

  • File: src/core/webview/ClineProvider.ts
  • Changes: Create distinct message types: 'fullState' (initial load) and 'update' (incremental)
  • Rationale: Allows webview to build state incrementally

Step 3: Update Message Handlers

  • File: webview-ui/src/context/ExtensionStateContext.tsx
  • Changes: Handle new incremental update messages, append rather than replace
  • Rationale: Prevents re-rendering entire message list

Step 4: Decouple CloudService Updates

  • File: src/extension.ts
  • Changes: Modify CloudService callback to only sync critical metadata, not trigger full UI refreshes
  • Rationale: Prevents cascade effect across all windows

Code Architecture Considerations

  • Follow existing message passing patterns in the codebase
  • Maintain backwards compatibility for history loading
  • Preserve existing state structure for other components

Testing Requirements

  • Unit Tests:
    • Test incremental updates correctly append messages
    • Test full state load still works for initial/reconnect
    • Test message ordering is preserved
  • Edge Cases:
    • Test reconnection after webview disposal
    • Test message updates during streaming

Performance Impact

  • Expected performance change: Significant improvement (from O(n²) to O(1) updates)
  • Benchmarking needed: Yes, measure time to update with 1000, 2000, 5000 messages
  • Optimization opportunities: Consider virtual scrolling for very long conversations

Security Considerations

  • No new security risks identified
  • Existing message sanitization remains in place

Migration Strategy

Not applicable - this is a performance optimization with no data migration needed

Rollback Plan

If issues arise, revert to sending full state (current behavior) by changing the message type back

Dependencies and Breaking Changes

  • External dependencies affected: None
  • API contract changes: None (internal only)
  • Breaking changes for users: None

Metadata

Metadata

Assignees

Labels

Issue - In ProgressSomeone is actively working on this. Should link to a PR soon.bugSomething isn't workingenhancementNew feature or request

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions