Optimize chat performance by reducing animations in inactive tabs

• Add isTabActive prop to ChatMessage
• Disable spinner in inactive tabs
• Reduce opacity for inactive content
• Hide loading indicator when inactive
• Pass tab state from RetrievalTesting
This commit is contained in:
yangdx 2025-10-17 21:17:01 +08:00
parent 04d2367147
commit dab1c35834
2 changed files with 23 additions and 6 deletions

View file

@ -45,7 +45,13 @@ export type MessageWithError = Message & {
}
// Restore original component definition and export
export const ChatMessage = ({ message }: { message: MessageWithError }) => { // Remove isComplete prop
export const ChatMessage = ({
message,
isTabActive = true
}: {
message: MessageWithError
isTabActive?: boolean
}) => {
const { t } = useTranslation()
const { theme } = useTheme()
const [katexPlugin, setKatexPlugin] = useState<((options?: KaTeXOptions) => any) | null>(null)
@ -148,8 +154,13 @@ export const ChatMessage = ({ message }: { message: MessageWithError }) => { //
} rounded-lg px-4 py-2`}
>
{/* Thinking process display - only for assistant messages */}
{/* Always render to prevent layout shift when switching tabs */}
{message.role === 'assistant' && (isThinking || thinkingTime !== null) && (
<div className="mb-2">
<div className={cn(
'mb-2',
// Reduce visual priority in inactive tabs while maintaining layout
!isTabActive && 'opacity-50'
)}>
<div
className="flex items-center text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors duration-200 text-sm cursor-pointer select-none"
onClick={() => {
@ -161,7 +172,8 @@ export const ChatMessage = ({ message }: { message: MessageWithError }) => { //
>
{isThinking ? (
<>
<LoaderIcon className="mr-2 size-4 animate-spin" />
{/* Only show spinner animation in active tab to save resources */}
{isTabActive && <LoaderIcon className="mr-2 size-4 animate-spin" />}
<span>{t('retrievePanel.chatMessage.thinking')}</span>
</>
) : (
@ -247,11 +259,12 @@ export const ChatMessage = ({ message }: { message: MessageWithError }) => { //
</ReactMarkdown>
</div>
)}
{(() => {
{/* Loading indicator - only show in active tab */}
{isTabActive && (() => {
// More comprehensive loading state check
const hasVisibleContent = finalDisplayContent && finalDisplayContent.trim() !== '';
const isLoadingState = !hasVisibleContent && !isThinking && !thinkingTime;
return isLoadingState && <LoaderIcon className="animate-spin duration-2000" />;
return isLoadingState && <LoaderIcon className="animate-spin duration-2000" />
})()}
</div>
)

View file

@ -103,6 +103,10 @@ const parseCOTContent = (content: string) => {
export default function RetrievalTesting() {
const { t } = useTranslation()
// Get current tab to determine if this tab is active (for performance optimization)
const currentTab = useSettingsStore.use.currentTab()
const isRetrievalTabActive = currentTab === 'retrieval'
const [messages, setMessages] = useState<MessageWithError[]>(() => {
try {
const history = useSettingsStore.getState().retrievalHistory || []
@ -716,7 +720,7 @@ export default function RetrievalTesting() {
<CopyIcon className="size-4" />
</Button>
)}
<ChatMessage message={message} />
<ChatMessage message={message} isTabActive={isRetrievalTabActive} />
{message.role === 'assistant' && (
<Button
onClick={() => handleCopyMessage(message)}