From a65e4ad0dbd9e281ae19971721c9c433d7c25421 Mon Sep 17 00:00:00 2001 From: i548450 Date: Tue, 9 Jun 2026 23:07:36 +0800 Subject: [PATCH] perf(customerservice): debounce SSE-driven refreshLists at 300ms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A burst of INCOMING_MESSAGE on a chatty conversation otherwise fires 2 list APIs per message (mine + unassigned). With 300ms trailing debounce, 5 messages within 100ms of each other collapse to 1 refresh. onMounted / onReconnect keep using refreshLists() directly — they need data immediately, not 300ms later. --- .../workbench/composables/useConversationStore.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/views/customerservice/workbench/composables/useConversationStore.ts b/src/views/customerservice/workbench/composables/useConversationStore.ts index 6eacb992..f0152475 100644 --- a/src/views/customerservice/workbench/composables/useConversationStore.ts +++ b/src/views/customerservice/workbench/composables/useConversationStore.ts @@ -1,5 +1,6 @@ import { defineStore } from 'pinia'; import { ref } from 'vue'; +import { useDebounceFn } from '@vueuse/core'; import type { Conversation, ConversationListItem, Message } from '@/chat-core'; import { listConversation, @@ -64,6 +65,12 @@ export const useConversationStore = defineStore('customerservice-conversation', await Promise.all([fetchList('mine'), fetchList('unassigned')]); } + // SSE-driven path collapses a burst of events into one refresh. Bursts of + // INCOMING_MESSAGE on a chatty conversation would otherwise fire 2 list + // APIs per message. onMounted / onReconnect keep using refreshLists() + // directly — they need the data immediately, not 300ms later. + const debouncedRefreshLists = useDebounceFn(refreshLists, 300); + async function openConversation(id: number) { const [detailRes, msgRes] = await Promise.all([ getConversation(id), @@ -138,7 +145,7 @@ export const useConversationStore = defineStore('customerservice-conversation', if (openedConversation.value?.id === p.conversationId) { appendMessage(p.message); } - refreshLists(); + debouncedRefreshLists(); } function onOutgoingMessageState(p: OutgoingMessageStatePayload) { @@ -156,21 +163,21 @@ export const useConversationStore = defineStore('customerservice-conversation', } function onConversationNew(_: ConversationNewPayload) { - refreshLists(); + debouncedRefreshLists(); } function onConversationClosed(p: ConversationClosedPayload) { if (openedConversation.value?.id === p.conversationId) { openedConversation.value = { ...openedConversation.value, status: 'CLOSED', closedAt: p.closedAt }; } - refreshLists(); + debouncedRefreshLists(); } function onConversationTransferred(p: ConversationTransferredPayload) { if (openedConversation.value?.id === p.conversationId) { openedConversation.value = { ...openedConversation.value, currentAgentId: p.toAgentId }; } - refreshLists(); + debouncedRefreshLists(); } function onAgentOnlineStatusChanged(p: AgentOnlineStatusPayload) {