From 7aa75f8ee0f3867aa2fc4132c1ea247aa03a97c6 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Tue, 24 Sep 2024 18:05:27 +0800 Subject: [PATCH] fix: chat page render performance (#2784) * fix: chat page render performance * fix: ts --- .../zh-cn/docs/development/upgrading/4811.md | 1 + .../core/chat/ChatContainer/useChat.ts | 72 +++++---- .../components/Logs/DetailLogsModal.tsx | 11 +- .../src/pages/chat/components/SliderApps.tsx | 2 +- projects/app/src/pages/chat/index.tsx | 100 ++++++------ projects/app/src/pages/chat/share.tsx | 144 ++++++++++-------- projects/app/src/pages/chat/team.tsx | 116 +++++++------- 7 files changed, 244 insertions(+), 202 deletions(-) diff --git a/docSite/content/zh-cn/docs/development/upgrading/4811.md b/docSite/content/zh-cn/docs/development/upgrading/4811.md index 32737cd23..32f9ca4db 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4811.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4811.md @@ -103,3 +103,4 @@ weight: 813 17. 修复 - 知识库选择权限问题。 18. 修复 - 空 chatId 发起对话,首轮携带用户选择时会异常。 19. 修复 - createDataset 接口,intro 为赋值。 +20. 修复 - 对话框渲染性能问题。 diff --git a/projects/app/src/components/core/chat/ChatContainer/useChat.ts b/projects/app/src/components/core/chat/ChatContainer/useChat.ts index 984ed8c55..581f83ceb 100644 --- a/projects/app/src/components/core/chat/ChatContainer/useChat.ts +++ b/projects/app/src/components/core/chat/ChatContainer/useChat.ts @@ -11,12 +11,12 @@ import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus'; import { getChatRecords } from '@/web/core/chat/api'; import { ChatStatusEnum } from '@fastgpt/global/core/chat/constants'; import { getNanoid } from '@fastgpt/global/common/string/tools'; -import { GetChatRecordsProps } from '@/global/core/chat/api'; import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination'; -import { PaginationResponse } from '../../../../../../../packages/web/common/fetch/type'; +import { PaginationResponse } from '@fastgpt/web/common/fetch/type'; import type { getPaginationRecordsBody } from '@/pages/api/core/chat/getPaginationRecords'; +import { GetChatTypeEnum } from '@/global/core/chat/constants'; -export const useChat = () => { +export const useChat = (params?: { chatId?: string; appId: string; type?: GetChatTypeEnum }) => { const ChatBoxRef = useRef(null); const variablesForm = useForm(); // plugin @@ -49,38 +49,41 @@ export const useChat = () => { ChatBoxRef.current?.restartChat?.(); }, [variablesForm]); - const useChatScrollData = useCallback((params: GetChatRecordsProps) => { - return useScrollPagination( - async (data: getPaginationRecordsBody): Promise> => { - const res = await getChatRecords(data); + const { + data: chatRecords, + ScrollData, + setData: setChatRecords, + total: totalRecordsCount + } = useScrollPagination( + async (data: getPaginationRecordsBody): Promise> => { + const res = await getChatRecords(data); - // First load scroll to bottom - if (data.offset === 0) { - function scrollToBottom() { - requestAnimationFrame( - ChatBoxRef?.current ? () => ChatBoxRef?.current?.scrollToBottom?.() : scrollToBottom - ); - } - scrollToBottom(); + // First load scroll to bottom + if (data.offset === 0) { + function scrollToBottom() { + requestAnimationFrame( + ChatBoxRef?.current ? () => ChatBoxRef?.current?.scrollToBottom?.() : scrollToBottom + ); } - - return { - ...res, - list: res.list.map((item) => ({ - ...item, - dataId: item.dataId || getNanoid(), - status: ChatStatusEnum.finish - })) - }; - }, - { - pageSize: 10, - refreshDeps: [params], - params, - scrollLoadType: 'top' + scrollToBottom(); } - ); - }, []); + + return { + ...res, + list: res.list.map((item) => ({ + ...item, + dataId: item.dataId || getNanoid(), + status: ChatStatusEnum.finish + })) + }; + }, + { + pageSize: 10, + refreshDeps: [params], + params, + scrollLoadType: 'top' + } + ); return { ChatBoxRef, @@ -89,7 +92,10 @@ export const useChat = () => { setPluginRunTab, clearChatRecords, resetVariables, - useChatScrollData + chatRecords, + ScrollData, + setChatRecords, + totalRecordsCount }; }; diff --git a/projects/app/src/pages/app/detail/components/Logs/DetailLogsModal.tsx b/projects/app/src/pages/app/detail/components/Logs/DetailLogsModal.tsx index 2e3d8c137..ba7045953 100644 --- a/projects/app/src/pages/app/detail/components/Logs/DetailLogsModal.tsx +++ b/projects/app/src/pages/app/detail/components/Logs/DetailLogsModal.tsx @@ -47,14 +47,11 @@ const DetailLogsModal = ({ pluginRunTab, setPluginRunTab, resetVariables, - useChatScrollData - } = useChat(); - const { - data: chatRecords, + chatRecords, ScrollData, - setData: setChatRecords, - total: totalRecordsCount - } = useChatScrollData(params); + setChatRecords, + totalRecordsCount + } = useChat(params); const { data: chat, isFetching } = useQuery( ['getChatDetail', chatId], diff --git a/projects/app/src/pages/chat/components/SliderApps.tsx b/projects/app/src/pages/chat/components/SliderApps.tsx index d1a500f10..34ed1788a 100644 --- a/projects/app/src/pages/chat/components/SliderApps.tsx +++ b/projects/app/src/pages/chat/components/SliderApps.tsx @@ -164,4 +164,4 @@ const SliderApps = ({ apps, activeAppId }: { apps: AppListItemType[]; activeAppI ); }; -export default SliderApps; +export default React.memo(SliderApps); diff --git a/projects/app/src/pages/chat/index.tsx b/projects/app/src/pages/chat/index.tsx index a18a8a22e..2440064e7 100644 --- a/projects/app/src/pages/chat/index.tsx +++ b/projects/app/src/pages/chat/index.tsx @@ -77,14 +77,11 @@ const Chat = ({ pluginRunTab, setPluginRunTab, resetVariables, - useChatScrollData - } = useChat(); - const { - data: chatRecords, + chatRecords, ScrollData, - setData: setChatRecords, - total: totalRecordsCount - } = useChatScrollData(params); + setChatRecords, + totalRecordsCount + } = useChat(params); // get chat app info const [chatData, setChatData] = useState(defaultChatData); @@ -166,6 +163,57 @@ const Chat = ({ ); const loading = isLoading; + const RenderHistorySlider = useMemo(() => { + const Children = ( + onDelHistory({ ...e, appId })} + onClearHistory={() => { + onClearHistories({ appId }); + }} + onSetHistoryTop={(e) => { + onUpdateHistory({ ...e, appId }); + }} + onSetCustomTitle={async (e) => { + onUpdateHistory({ + appId, + chatId: e.chatId, + customTitle: e.title + }); + }} + /> + ); + + return isPc || !appId ? ( + {Children} + ) : ( + + + {Children} + + ); + }, [ + appId, + chatData.app.avatar, + chatData.app.name, + isOpenSlider, + isPc, + onClearHistories, + onCloseSlider, + onDelHistory, + onUpdateHistory, + t + ]); + return ( @@ -179,43 +227,7 @@ const Chat = ({ {/* pc always show history. */} - {((children: React.ReactNode) => { - return isPc || !appId ? ( - {children} - ) : ( - - - {children} - - ); - })( - onDelHistory({ ...e, appId })} - onClearHistory={() => { - onClearHistories({ appId }); - }} - onSetHistoryTop={(e) => { - onUpdateHistory({ ...e, appId }); - }} - onSetCustomTitle={async (e) => { - onUpdateHistory({ - appId, - chatId: e.chatId, - customTitle: e.title - }); - }} - /> - )} + {RenderHistorySlider} {/* chat container */} v); - const { - ChatBoxRef, - variablesForm, - pluginRunTab, - setPluginRunTab, - resetVariables, - useChatScrollData - } = useChat(); const params = useMemo(() => { return { chatId, @@ -105,11 +92,16 @@ const OutLink = ({ }; }, [chatData.appId, chatId, outLinkUid, shareId]); const { - data: chatRecords, + ChatBoxRef, + variablesForm, + pluginRunTab, + setPluginRunTab, + resetVariables, + chatRecords, ScrollData, - setData: setChatRecords, - total: totalRecordsCount - } = useChatScrollData(params); + setChatRecords, + totalRecordsCount + } = useChat(params); const startChat = useCallback( async ({ @@ -233,6 +225,73 @@ const OutLink = ({ useMount(() => { setIdEmbed(window !== top); }); + + const RenderHistoryList = useMemo(() => { + const Children = ( + + onDelHistory({ appId: chatData.appId, chatId, shareId, outLinkUid }) + } + onClearHistory={() => { + onClearHistories({ shareId, outLinkUid }); + }} + onSetHistoryTop={(e) => { + onUpdateHistory({ + ...e, + appId: chatData.appId, + shareId, + outLinkUid + }); + }} + onSetCustomTitle={(e) => { + onUpdateHistory({ + appId: chatData.appId, + chatId: e.chatId, + customTitle: e.title, + shareId, + outLinkUid + }); + }} + /> + ); + + if (showHistory !== '1') return null; + + return isPc ? ( + {Children} + ) : ( + + + + {Children} + + + ); + }, [ + chatData.app.avatar, + chatData.app.name, + chatData.appId, + isOpenSlider, + isPc, + onClearHistories, + onCloseSlider, + onDelHistory, + onUpdateHistory, + outLinkUid, + shareId, + showHistory, + t + ]); + const loading = isLoading; return ( @@ -244,54 +303,7 @@ const OutLink = ({ : { p: [0, 5] })} > - {showHistory === '1' && - ((children: React.ReactNode) => { - return isPc ? ( - {children} - ) : ( - - - - {children} - - - ); - })( - - onDelHistory({ appId: chatData.appId, chatId, shareId, outLinkUid }) - } - onClearHistory={() => { - onClearHistories({ shareId, outLinkUid }); - }} - onSetHistoryTop={(e) => { - onUpdateHistory({ - ...e, - appId: chatData.appId, - shareId, - outLinkUid - }); - }} - onSetCustomTitle={(e) => { - onUpdateHistory({ - appId: chatData.appId, - chatId: e.chatId, - customTitle: e.title, - shareId, - outLinkUid - }); - }} - /> - )} + {RenderHistoryList} {/* chat container */} { onChangeChatId } = useContextSelector(ChatContext, (v) => v); - const { - ChatBoxRef, - variablesForm, - pluginRunTab, - setPluginRunTab, - resetVariables, - useChatScrollData - } = useChat(); const params = useMemo(() => { return { appId, @@ -85,11 +77,16 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => { }; }, [appId, chatId, teamId, teamToken]); const { - data: chatRecords, + ChatBoxRef, + variablesForm, + pluginRunTab, + setPluginRunTab, + resetVariables, + chatRecords, ScrollData, - setData: setChatRecords, - total: totalRecordsCount - } = useChatScrollData(params); + setChatRecords, + totalRecordsCount + } = useChat(params); const startChat = useCallback( async ({ @@ -181,6 +178,61 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => { } ); + const RenderHistoryList = useMemo(() => { + const Children = ( + onDelHistory({ ...e, appId, teamId, teamToken })} + onClearHistory={() => { + onClearHistories({ appId, teamId, teamToken }); + }} + onSetHistoryTop={(e) => { + onUpdateHistory({ ...e, teamId, teamToken, appId }); + }} + onSetCustomTitle={async (e) => { + onUpdateHistory({ + appId, + chatId: e.chatId, + customTitle: e.title, + teamId, + teamToken + }); + }} + /> + ); + + return isPc || !appId ? ( + {Children} + ) : ( + + + {Children} + + ); + }, [ + appId, + chatData.app.avatar, + chatData.app.name, + isOpenSlider, + isPc, + onClearHistories, + onCloseSlider, + onDelHistory, + onUpdateHistory, + t, + teamId, + teamToken + ]); + const loading = isLoading; return ( @@ -195,45 +247,7 @@ const Chat = ({ myApps }: { myApps: AppListItemType[] }) => { - {((children: React.ReactNode) => { - return isPc || !appId ? ( - {children} - ) : ( - - - {children} - - ); - })( - onDelHistory({ ...e, appId, teamId, teamToken })} - onClearHistory={() => { - onClearHistories({ appId, teamId, teamToken }); - }} - onSetHistoryTop={(e) => { - onUpdateHistory({ ...e, teamId, teamToken, appId }); - }} - onSetCustomTitle={async (e) => { - onUpdateHistory({ - appId, - chatId: e.chatId, - customTitle: e.title, - teamId, - teamToken - }); - }} - /> - )} + {RenderHistoryList} {/* chat container */}