perf(web): narrow message state subscriptions

- web/src/components/AssistantChat/messages/UserMessage.tsx now subscribes only to role, text, status,
  and localId instead of the entire message object to avoid re-renders caused by unrelated message state
  changes (hover/isLast/etc.).
- web/src/components/AssistantChat/messages/SystemMessage.tsx now subscribes only to role, text, and icon
  for the same reason.
- This reduces unnecessary renders observed in React DevTools without changing message UI or behavior.
This commit is contained in:
weishu
2025-12-19 21:48:03 +08:00
parent d2ad977394
commit 05c2cbb724
2 changed files with 28 additions and 13 deletions
@@ -3,13 +3,19 @@ import { getEventPresentation } from '@/chat/presentation'
import type { HappyChatMessageMetadata } from '@/lib/assistant-runtime'
export function HappySystemMessage() {
const message = useAssistantState(({ message }) => message)
if (message.role !== 'system') return null
const role = useAssistantState(({ message }) => message.role)
const text = useAssistantState(({ message }) => {
if (message.role !== 'system') return ''
return message.content[0]?.type === 'text' ? message.content[0].text : ''
})
const icon = useAssistantState(({ message }) => {
if (message.role !== 'system') return null
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
const event = custom?.kind === 'event' ? custom.event : undefined
return event ? getEventPresentation(event).icon : null
})
const text = message.content[0]?.type === 'text' ? message.content[0].text : ''
const custom = message.metadata.custom as Partial<HappyChatMessageMetadata> | undefined
const event = custom?.kind === 'event' ? custom.event : undefined
const icon = event ? getEventPresentation(event).icon : null
if (role !== 'system') return null
return (
<div className="py-1">