Skip to content

fix(web): reduce unnecessary re-renders in chat reference panel#1042

Merged
brendan-kellam merged 7 commits intomainfrom
brendan/fix-SOU-725
Mar 25, 2026
Merged

fix(web): reduce unnecessary re-renders in chat reference panel#1042
brendan-kellam merged 7 commits intomainfrom
brendan/fix-SOU-725

Conversation

@brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Mar 25, 2026

Summary

  • Extracts ReferencedSourcesListView's map body into a memoized FileSourceItem component with its own useQuery, stable useCallbacks for ref and onExpandedChanged, and scoped hover/selected reference props — preventing unaffected file items from re-rendering on hover/select changes
  • Moves all hover/select highlight logic (decorations, state fields, event handlers) into a dedicated referencesHighlightExtension — hover and select state changes are now dispatched as CodeMirror StateEffects rather than causing the extensions array to be recreated
  • Fixes useExtensionWithDependency to exclude extensionFactory from its useMemo deps, making languageExtension and keymapExtension stable references across renders

Fixes SOU-725

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Improved inline source viewing: clearer hover and selection highlights in code snippets and per-file loading/error states when viewing referenced files.
    • Added a container to fetch and render referenced file contents more reliably.
    • Duplicate-chat links now resolve to the primary chat domain consistently.
  • Bug Fixes

    • Improved ask-thread rendering performance, especially when hovering over or selecting citations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

This comment has been minimized.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 25, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 578bfa50-3f2a-437d-89a8-72a86c46e575

📥 Commits

Reviewing files that changed from the base of the PR and between 9c1c5a6 and 0f32b5f.

📒 Files selected for processing (3)
  • packages/web/src/features/chat/components/chatThread/referencedFileSourceListItemContainer.tsx
  • packages/web/src/features/chat/components/chatThread/referencedSourcesListView.tsx
  • packages/web/src/features/chat/components/chatThread/referencesHighlightExtension.ts

Walkthrough

Extracts CodeMirror reference decoration/interaction into a reusable extension, moves per-file fetching into a memoized container component, adjusts extension hook memoization, replaces domain routing with a single-tenant constant, and adds a changelog entry for improved citation rendering performance.

Changes

Cohort / File(s) Summary
References Highlight Extension
packages/web/src/features/chat/components/chatThread/referencesHighlightExtension.ts
New CodeMirror extension createReferencesHighlightExtension plus exported effects setHoveredIdEffect and setSelectedIdEffect; builds per-line decorations and handles mouseover/mouseout/click to update hover/selection state and callbacks.
Referenced File Item — editor integration
packages/web/src/features/chat/components/chatThread/referencedFileSourceListItem.tsx
Removed in-component decoration/event handling; now injects the new extension via useExtensionWithDependency, dispatches hover/selection effects to sync external state, and centralizes basicSetup into CODEMIRROR_BASIC_SETUP.
Referenced File Item Container
packages/web/src/features/chat/components/chatThread/referencedFileSourceListItemContainer.tsx
Added memoized client component that queries getFileSource (with caching), renders loading/error states, and forwards fetched source/language/repo metadata plus editor/ref and expand handlers to the list item.
Sources List View
packages/web/src/features/chat/components/chatThread/referencedSourcesListView.tsx
Removed parent-level useQueries and loading/error branching; renders ReferencedFileSourceListItemContainer per source and maps hovered/selected reference props per-file; forwards editor ref and expanded callbacks.
Hook Change
packages/web/src/hooks/useExtensionWithDependency.ts
Changed memoization to create the extension once per compartment ([compartment] deps); extensionFactory removed from useMemo deps and effect still reconfigures based on provided deps (eslint-disable added).
Chat Thread Routing
packages/web/src/features/chat/components/chatThread/chatThread.tsx
Removed useParams/params.domain usage; duplicate-chat navigation now uses SINGLE_TENANT_ORG_DOMAIN constant; updated onDuplicate dependencies.
Changelog
CHANGELOG.md
Added ## [Unreleased]### Fixed entry noting improved ask-thread rendering performance for citation hover/selection.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant EditorView as CodeMirror EditorView
  participant Extension as referencesHighlightExtension
  participant ReactComp as ReferencedFileSourceListItem
  participant Container as ReferencedFileSourceListItemContainer

  User->>EditorView: hover / move / click
  EditorView->>Extension: DOM event handlers (posAtCoords)
  Extension->>Extension: resolve reference under cursor (shortest matching range)
  alt hover changed
    Extension->>ReactComp: onHoveredReferenceChanged(reference?)
  end
  alt click toggles selection
    Extension->>ReactComp: onSelectedReferenceChanged(reference?)
  end
  Container->>ReactComp: provide fetched file source + references
  ReactComp->>EditorView: dispatch setHoveredIdEffect / setSelectedIdEffect to sync external state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the PR: reducing unnecessary re-renders in the chat reference panel through component memoization and state management refactoring.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch brendan/fix-SOU-725

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

brendan-kellam and others added 3 commits March 24, 2026 17:56
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n file

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/web/src/features/chat/components/chatThread/chatThread.tsx`:
- Line 34: The code hardcodes SINGLE_TENANT_ORG_DOMAIN when building the
duplicate-chat route; instead use the active route/domain value (e.g., the
domain from the Next router query or the existing component state) so duplicates
stay within the current org. Locate occurrences of SINGLE_TENANT_ORG_DOMAIN in
chatThread.tsx (and the duplicate handler such as handleDuplicateChat or where
router.push/Link is used around lines 34 and 343-345) and replace them with the
current domain variable (e.g., router.query.domain or the component’s
selectedDomain prop/state) when constructing the `/app/{domain}/chat/{chatId}`
path. Ensure the domain falls back to SINGLE_TENANT_ORG_DOMAIN only if the
active route domain is undefined.

In
`@packages/web/src/features/chat/components/chatThread/referencedSourcesListView.tsx`:
- Around line 196-215: The parent effect that scrolls to a citation is exiting
early when FileSourceItem asynchronously fetches file data, so ensure the parent
still exposes the file anchor/editor reference (or is notified when the file
finishes loading) instead of relying on FileSourceItem's render timing;
specifically, in the render loop around getFileId(fileSource) and
FileSourceItem, either (A) render a stable placeholder anchor/editor ref in the
parent for each fileId (so the existing scroll effect can find the anchor even
on cache miss) and continue to forward setEditorRef into FileSourceItem, or (B)
add an explicit onFileLoaded callback prop on FileSourceItem and call
onFileLoaded(fileId) when its query completes so the parent scroll effect can
retry; update usages of FileSourceItem, getFileId, setEditorRef, and
collapsedFileIds accordingly.

In
`@packages/web/src/features/chat/components/chatThread/referencesHighlightExtension.ts`:
- Around line 77-84: The loop iterating from range.startLine to range.endLine
calls state.doc.line(line) without checking lower bounds; add a guard for line <
1 (e.g., if (line < 1) continue;) before any state.doc.line(...) calls so
negative or zero startLine values don't cause a RangeError; update the loop that
uses range.startLine, range.endLine, isSelected,
decorations.push(selectedLineDecoration.range(state.doc.line(line).from)) and
similar calls to short-circuit out-of-range low values.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e4073964-112b-43e5-82cb-cb14d1ad570b

📥 Commits

Reviewing files that changed from the base of the PR and between a795a34 and 9c1c5a6.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • packages/web/src/features/chat/components/chatThread/chatThread.tsx
  • packages/web/src/features/chat/components/chatThread/referencedFileSourceListItem.tsx
  • packages/web/src/features/chat/components/chatThread/referencedSourcesListView.tsx
  • packages/web/src/features/chat/components/chatThread/referencesHighlightExtension.ts
  • packages/web/src/hooks/useExtensionWithDependency.ts

@brendan-kellam brendan-kellam merged commit 596df83 into main Mar 25, 2026
6 checks passed
@brendan-kellam brendan-kellam deleted the brendan/fix-SOU-725 branch March 25, 2026 01:18
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