🧵 fix: Prevent Unnecessary Re-renders when Loading Chats (#5189)

* chore: typing

* chore: typing

* fix: enhance message scrolling logic to handle empty messages tree and ref checks

* fix: optimize message selection logic with useCallback for better performance

* chore: typing

* refactor: optimize icon rendering

* refactor: further optimize chat props

* fix: remove unnecessary console log in useQueryParams cleanup

* refactor: add queryClient to reset message data on new conversation initiation

* refactor: update data-testid attributes for consistency and improve code readability

* refactor: integrate queryClient to reset message data on new conversation initiation
This commit is contained in:
Danny Avila 2025-01-06 10:32:44 -05:00 committed by GitHub
parent 7987e04a2c
commit b01c744eb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 184 additions and 88 deletions

View file

@ -1,26 +1,23 @@
import React, { useMemo, memo } from 'react';
import { useGetEndpointsQuery } from 'librechat-data-provider/react-query';
import type { TMessage, TPreset, Assistant, Agent } from 'librechat-data-provider';
import type { TMessageProps } from '~/common';
import type { Assistant, Agent, TMessage } from 'librechat-data-provider';
import ConvoIconURL from '~/components/Endpoints/ConvoIconURL';
import { getEndpointField, getIconEndpoint } from '~/utils';
import Icon from '~/components/Endpoints/Icon';
const MessageIcon = memo(
(
props: Pick<TMessageProps, 'message' | 'conversation'> & {
assistant?: Assistant;
agent?: Agent;
},
) => {
(props: {
iconData?: TMessage & { modelLabel?: string };
assistant?: Assistant;
agent?: Agent;
}) => {
const { data: endpointsConfig } = useGetEndpointsQuery();
const { message, conversation, assistant, agent } = props;
const { iconData, assistant, agent } = props;
const assistantName = useMemo(() => assistant?.name ?? '', [assistant]);
const assistantAvatar = useMemo(() => assistant?.metadata?.avatar ?? '', [assistant]);
const agentName = useMemo(() => props.agent?.name ?? '', [props.agent]);
const agentAvatar = useMemo(() => props.agent?.avatar?.filepath ?? '', [props.agent]);
const isCreatedByUser = useMemo(() => message?.isCreatedByUser ?? false, [message]);
let avatarURL = '';
@ -30,21 +27,10 @@ const MessageIcon = memo(
avatarURL = agentAvatar;
}
const messageSettings = useMemo(
() => ({
...(conversation ?? {}),
...({
...(message ?? {}),
iconURL: message?.iconURL ?? '',
} as TMessage),
}),
[conversation, message],
);
const iconURL = messageSettings.iconURL;
const iconURL = iconData?.iconURL;
const endpoint = useMemo(
() => getIconEndpoint({ endpointsConfig, iconURL, endpoint: messageSettings.endpoint }),
[endpointsConfig, iconURL, messageSettings.endpoint],
() => getIconEndpoint({ endpointsConfig, iconURL, endpoint: iconData?.endpoint }),
[endpointsConfig, iconURL, iconData?.endpoint],
);
const endpointIconURL = useMemo(
@ -52,10 +38,11 @@ const MessageIcon = memo(
[endpointsConfig, endpoint],
);
if (isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) {
if (iconData?.isCreatedByUser !== true && iconURL != null && iconURL.includes('http')) {
return (
<ConvoIconURL
preset={messageSettings as typeof messageSettings & TPreset}
iconURL={iconURL}
modelLabel={iconData?.modelLabel}
context="message"
assistantAvatar={assistantAvatar}
agentAvatar={agentAvatar}
@ -68,10 +55,10 @@ const MessageIcon = memo(
return (
<Icon
isCreatedByUser={isCreatedByUser}
isCreatedByUser={iconData?.isCreatedByUser ?? false}
endpoint={endpoint}
iconURL={avatarURL || endpointIconURL}
model={message?.model ?? conversation?.model}
model={iconData?.model}
assistantName={assistantName}
agentName={agentName}
size={28.8}