Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Cody Chat UI rendering reconciliation #5850

Merged
merged 2 commits into from
Oct 10, 2024
Merged

Conversation

vovakulikov
Copy link
Contributor

Fixes part of https://linear.app/sourcegraph/issue/CODY-3943/optimize-performance-for-large-chat-windows-in-cody

It looks like since #5036 we've lost memoization in a few places. As a result, our chat UI doesn't perform well with more than 4-5 messages (depending on how long these chat messages are)

This PR tries to improve it by fixing memoization on expensive components (Transcript, HumanMessage, ...etc)

Before After
Screen.Recording.2024-10-08.at.20.41.09.mov
Screen.Recording.2024-10-08.at.20.39.49.mov

This PR also fixes a problem with one-box intention detection; previously, it produced a state where we didn't have a follow-up message UI during intent resolution.

Test plan

  • Check with the React profile that we don't render components during message response in places where we don't need to re-render anything
  • Check that intent detection in one-box doesn't produce UI flashes

@vovakulikov vovakulikov requested review from thenamankumar and a team October 8, 2024 23:48
@vovakulikov vovakulikov self-assigned this Oct 8, 2024
Copy link

github-actions bot commented Oct 8, 2024

‼️ Hey @sourcegraph/cody-security, please review this PR carefully as it introduces the usage of an unsafe_ function or abuses PromptString.

Copy link
Contributor

@abeatrix abeatrix left a comment

Choose a reason for hiding this comment

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

Tested locally and confirmed the states were not re-render.

I was looking into a similar issue for the editor state. Would appreciate your review on it as well since I think there are a few things I can clean up on my PR after yours is merged 😄 #5847

@abeatrix
Copy link
Contributor

abeatrix commented Oct 9, 2024

(Not a blocker) would be great to have a test covering transcript rendering for regression if possible 😄

Copy link
Contributor

@dominiccooney dominiccooney left a comment

Choose a reason for hiding this comment

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

We need a trivial renaming to keep the PromptString lint results accurate.


useEffect(() => {
const changedProps = Object.entries(props).reduce(
(ps, [k, v]) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Our lints for PromptString rely on only using ps to refer to the PromptString formatter. This ensures we never alias ps, which can be used to defeat the static checks for correct PromptString usage.

We could write a more complicated check that understands JavaScript scoping to allow the use you have here, or only lint files which import "the" ps, but until we do that, can you rename these variables to anything else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, renamed it in my last commit

Copy link
Contributor

@dominiccooney dominiccooney left a comment

Choose a reason for hiding this comment

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

Approving for the ps fixes, thank you. I have not reviewed the rest in detail but I have some questions and suggestions inline.

I think the message output stuttering has a different cause, see #5296 (comment)

@@ -0,0 +1,23 @@
import { useEffect, useRef } from 'react'

export function useTracePropsUpdate(props: any) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add a comment here that this is for debugging with advice about how to use it.

From time to team people do mass-deletions based on use. You probably intend for this to stick around.

@@ -389,6 +389,17 @@ const TranscriptInteraction: FC<TranscriptInteractionProps> = memo(props => {
)
}, isEqual)

function useMutatedValue<T>(value?: T): [MutableRefObject<T | undefined>, setValue: (value: T) => void] {
Copy link
Contributor

Choose a reason for hiding this comment

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

You should document that this should not be used for rendering and won't cause re-rendering.

@@ -180,7 +180,7 @@ const TranscriptInteraction: FC<TranscriptInteractionProps> = memo(props => {
smartApplyEnabled,
} = props

const [intentResults, setIntentResults] = useState<
const [intentResults, setIntentResults] = useMutatedValue<
Copy link
Contributor

Choose a reason for hiding this comment

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

Why isn't simply useRef enough here?

@vovakulikov vovakulikov merged commit 9cd3b64 into main Oct 10, 2024
19 checks passed
@vovakulikov vovakulikov deleted the vk/fix-rendering-perf branch October 10, 2024 02:44
PriNova pushed a commit to PriNova/Cody-Community-Edition that referenced this pull request Oct 11, 2024
Fixes part of
https://linear.app/sourcegraph/issue/CODY-3943/optimize-performance-for-large-chat-windows-in-cody

It looks like since sourcegraph#5036 we've
lost memoization in a few places. As a result, our chat UI doesn't
perform well with more than 4-5 messages (depending on how long these
chat messages are)

This PR tries to improve it by fixing memoization on expensive
components (Transcript, HumanMessage, ...etc)

| Before | After |
| ------- | ------- |
| <video
src="https://github.com/user-attachments/assets/79e7b93c-ac82-4a8c-9b2e-6c712af3fb2c"
/> | <video
src="https://github.com/user-attachments/assets/223b3513-0f30-47cc-b24c-c54f4861329c"
/> |

This PR also fixes a problem with one-box intention detection;
previously, it produced a state where we didn't have a follow-up message
UI during intent resolution.

## Test plan
- Check with the React profile that we don't render components during
message response in places where we don't need to re-render anything
- Check that intent detection in one-box doesn't produce UI flashes
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.

4 participants