mirror of
https://github.com/LifeArchiveProject/WeChatDataAnalysis.git
synced 2026-06-18 15:54:08 +08:00
improvement(log): 补充聊天消息与会话加载阶段日志
- 为会话加载、刷新和联系人初始化补充阶段性 trace - 为消息加载、归一化、状态提交和媒体刷新补充耗时日志 - 便于定位聊天页卡顿和加载异常
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
getVoiceDurationInSeconds,
|
||||
getVoiceWidth
|
||||
} from '~/lib/chat/formatters'
|
||||
import { createPerfTrace } from '~/lib/chat/perf-logger'
|
||||
import { createMessageNormalizer, dedupeMessagesById } from '~/lib/chat/message-normalizer'
|
||||
|
||||
export const useChatMessages = ({
|
||||
@@ -410,9 +411,15 @@ export const useChatMessages = ({
|
||||
const loadMessages = async ({ username, reset }) => {
|
||||
if (!username || !selectedAccount.value) return
|
||||
|
||||
logMessagePhase('loadMessages:enter', {
|
||||
username,
|
||||
reset
|
||||
const trace = createPerfTrace('chat-messages', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
selectedUsername: String(selectedContact.value?.username || '').trim(),
|
||||
username: String(username || '').trim(),
|
||||
reset: !!reset
|
||||
})
|
||||
|
||||
trace.log('loadMessages:enter', {
|
||||
activeMessagesFor: String(activeMessagesFor.value || '').trim()
|
||||
})
|
||||
messagesError.value = ''
|
||||
isLoadingMessages.value = true
|
||||
@@ -438,46 +445,37 @@ export const useChatMessages = ({
|
||||
if (realtimeEnabled.value) {
|
||||
params.source = 'realtime'
|
||||
}
|
||||
logMessagePhase('loadMessages:request:start', {
|
||||
username,
|
||||
reset,
|
||||
trace.log('loadMessages:request:start', {
|
||||
offset,
|
||||
existingCount: existing.length,
|
||||
renderTypeFilter: messageTypeFilter.value,
|
||||
realtime: !!realtimeEnabled.value
|
||||
})
|
||||
const response = await api.listChatMessages(params)
|
||||
logMessagePhase('loadMessages:request:end', {
|
||||
username,
|
||||
reset,
|
||||
trace.log('loadMessages:request:end', {
|
||||
rawCount: Array.isArray(response?.messages) ? response.messages.length : 0,
|
||||
total: Number(response?.total || 0),
|
||||
hasMore: response?.hasMore
|
||||
})
|
||||
|
||||
const raw = response?.messages || []
|
||||
logMessagePhase('loadMessages:normalize:start', {
|
||||
username,
|
||||
trace.log('loadMessages:normalize:start', {
|
||||
rawCount: raw.length
|
||||
})
|
||||
const mapped = dedupeMessagesById(raw.map(normalizeMessage))
|
||||
logMessagePhase('loadMessages:normalize:end', {
|
||||
username,
|
||||
trace.log('loadMessages:normalize:end', {
|
||||
mappedCount: mapped.length,
|
||||
renderTypeCounts: summarizeRenderTypes(mapped)
|
||||
})
|
||||
|
||||
if (activeMessagesFor.value !== username) {
|
||||
logMessagePhase('loadMessages:abort-stale', {
|
||||
username,
|
||||
trace.log('loadMessages:abort-stale', {
|
||||
activeMessagesFor: activeMessagesFor.value
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
logMessagePhase('loadMessages:state-commit:start', {
|
||||
username,
|
||||
reset,
|
||||
trace.log('loadMessages:state-commit:start', {
|
||||
mappedCount: mapped.length
|
||||
})
|
||||
if (reset) {
|
||||
@@ -496,8 +494,7 @@ export const useChatMessages = ({
|
||||
[username]: [...older, ...existing]
|
||||
}
|
||||
}
|
||||
logMessagePhase('loadMessages:state-commit:end', {
|
||||
username,
|
||||
trace.log('loadMessages:state-commit:end', {
|
||||
storedCount: (allMessages.value[username] || []).length
|
||||
})
|
||||
|
||||
@@ -508,18 +505,14 @@ export const useChatMessages = ({
|
||||
hasMore: response?.hasMore
|
||||
}
|
||||
}
|
||||
logMessagePhase('loadMessages:meta-commit:end', {
|
||||
username,
|
||||
trace.log('loadMessages:meta-commit:end', {
|
||||
total: Number(response?.total || 0),
|
||||
hasMore: response?.hasMore
|
||||
})
|
||||
|
||||
logMessagePhase('loadMessages:nextTick:start', {
|
||||
username
|
||||
})
|
||||
trace.log('loadMessages:nextTick:start')
|
||||
await nextTick()
|
||||
logMessagePhase('loadMessages:nextTick:end', {
|
||||
username,
|
||||
trace.log('loadMessages:nextTick:end', {
|
||||
renderedCount: (allMessages.value[username] || []).length
|
||||
})
|
||||
const nextContainer = messageContainerRef.value
|
||||
@@ -532,13 +525,16 @@ export const useChatMessages = ({
|
||||
}
|
||||
}
|
||||
updateJumpToBottomState()
|
||||
logMessagePhase('loadMessages:scroll:end', {
|
||||
username,
|
||||
trace.log('loadMessages:scroll:end', {
|
||||
hasContainer: !!nextContainer,
|
||||
scrollTop: nextContainer ? nextContainer.scrollTop : null,
|
||||
scrollHeight: nextContainer ? nextContainer.scrollHeight : null
|
||||
})
|
||||
} catch (error) {
|
||||
trace.log('loadMessages:error', {
|
||||
message: String(error?.message || ''),
|
||||
errorName: String(error?.name || '')
|
||||
})
|
||||
console.error('[chat-messages] loadMessages:error', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
username: String(username || '').trim(),
|
||||
@@ -548,9 +544,7 @@ export const useChatMessages = ({
|
||||
messagesError.value = error?.message || '加载聊天记录失败'
|
||||
} finally {
|
||||
isLoadingMessages.value = false
|
||||
logMessagePhase('loadMessages:exit', {
|
||||
username,
|
||||
reset,
|
||||
trace.log('loadMessages:exit', {
|
||||
loading: isLoadingMessages.value,
|
||||
error: messagesError.value
|
||||
})
|
||||
@@ -571,9 +565,24 @@ export const useChatMessages = ({
|
||||
|
||||
const refreshCurrentMessageMedia = async () => {
|
||||
if (!selectedContact.value?.username) return
|
||||
const trace = createPerfTrace('chat-messages', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
username: String(selectedContact.value?.username || '').trim(),
|
||||
action: 'refreshCurrentMessageMedia'
|
||||
})
|
||||
trace.log('refreshCurrentMessageMedia:start', {
|
||||
localMediaVersion: Number(localMediaVersion.value || 0)
|
||||
})
|
||||
bumpLocalMediaVersion()
|
||||
trace.log('refreshCurrentMessageMedia:version-bumped', {
|
||||
localMediaVersion: Number(localMediaVersion.value || 0)
|
||||
})
|
||||
renormalizeLoadedMessages(selectedContact.value.username)
|
||||
trace.log('refreshCurrentMessageMedia:renormalized', {
|
||||
renderedCount: (allMessages.value[selectedContact.value.username] || []).length
|
||||
})
|
||||
await nextTick()
|
||||
trace.log('refreshCurrentMessageMedia:end')
|
||||
}
|
||||
|
||||
const refreshRealtimeIncremental = async () => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { normalizeSessionPreview } from '~/lib/chat/formatters'
|
||||
import { createPerfTrace } from '~/lib/chat/perf-logger'
|
||||
|
||||
const SESSION_LIST_WIDTH_KEY = 'ui.chat.session_list_width_physical'
|
||||
const SESSION_LIST_WIDTH_KEY_LEGACY = 'ui.chat.session_list_width'
|
||||
@@ -170,6 +171,14 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
return []
|
||||
}
|
||||
|
||||
const trace = createPerfTrace('chat-sessions', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
action: 'loadSessionsForSelectedAccount'
|
||||
})
|
||||
trace.log('loadSessions:start', {
|
||||
realtimeEnabled: !!realtimeEnabled?.value
|
||||
})
|
||||
|
||||
const fetchSessions = async (source) => {
|
||||
const params = {
|
||||
account: selectedAccount.value,
|
||||
@@ -184,18 +193,38 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
let sessionsResp = null
|
||||
if (realtimeEnabled?.value) {
|
||||
try {
|
||||
trace.log('loadSessions:request:start', {
|
||||
source: 'realtime'
|
||||
})
|
||||
sessionsResp = await fetchSessions('realtime')
|
||||
trace.log('loadSessions:request:end', {
|
||||
source: 'realtime',
|
||||
rawCount: Array.isArray(sessionsResp?.sessions) ? sessionsResp.sessions.length : 0
|
||||
})
|
||||
} catch {
|
||||
sessionsResp = null
|
||||
trace.log('loadSessions:request:error', {
|
||||
source: 'realtime'
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!sessionsResp) {
|
||||
trace.log('loadSessions:request:start', {
|
||||
source: 'default'
|
||||
})
|
||||
sessionsResp = await fetchSessions('')
|
||||
trace.log('loadSessions:request:end', {
|
||||
source: 'default',
|
||||
rawCount: Array.isArray(sessionsResp?.sessions) ? sessionsResp.sessions.length : 0
|
||||
})
|
||||
}
|
||||
|
||||
const sessions = Array.isArray(sessionsResp?.sessions) ? sessionsResp.sessions : []
|
||||
contacts.value = mapSessions(sessions)
|
||||
contactsError.value = ''
|
||||
trace.log('loadSessions:end', {
|
||||
contactCount: contacts.value.length
|
||||
})
|
||||
return contacts.value
|
||||
}
|
||||
|
||||
@@ -208,6 +237,14 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
const desiredSource = (sourceOverride != null)
|
||||
? String(sourceOverride || '').trim()
|
||||
: (realtimeEnabled?.value ? 'realtime' : '')
|
||||
const trace = createPerfTrace('chat-sessions', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
action: 'refreshSessionsForSelectedAccount',
|
||||
desiredSource
|
||||
})
|
||||
trace.log('refreshSessions:start', {
|
||||
previousUsername
|
||||
})
|
||||
|
||||
const params = {
|
||||
account: selectedAccount.value,
|
||||
@@ -219,15 +256,35 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
let sessionsResp = null
|
||||
if (desiredSource) {
|
||||
try {
|
||||
trace.log('refreshSessions:request:start', {
|
||||
source: desiredSource
|
||||
})
|
||||
sessionsResp = await api.listChatSessions({ ...params, source: desiredSource })
|
||||
trace.log('refreshSessions:request:end', {
|
||||
source: desiredSource,
|
||||
rawCount: Array.isArray(sessionsResp?.sessions) ? sessionsResp.sessions.length : 0
|
||||
})
|
||||
} catch {
|
||||
sessionsResp = null
|
||||
trace.log('refreshSessions:request:error', {
|
||||
source: desiredSource
|
||||
})
|
||||
}
|
||||
}
|
||||
if (!sessionsResp) {
|
||||
try {
|
||||
trace.log('refreshSessions:request:start', {
|
||||
source: 'default'
|
||||
})
|
||||
sessionsResp = await api.listChatSessions(params)
|
||||
trace.log('refreshSessions:request:end', {
|
||||
source: 'default',
|
||||
rawCount: Array.isArray(sessionsResp?.sessions) ? sessionsResp.sessions.length : 0
|
||||
})
|
||||
} catch {
|
||||
trace.log('refreshSessions:request:error', {
|
||||
source: 'default'
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -240,6 +297,10 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
const matched = nextContacts.find((contact) => contact.username === previousUsername)
|
||||
if (matched) selectedContact.value = matched
|
||||
}
|
||||
trace.log('refreshSessions:end', {
|
||||
contactCount: nextContacts.length,
|
||||
selectedUsername: String(selectedContact.value?.username || '').trim()
|
||||
})
|
||||
}
|
||||
|
||||
const loadContacts = async () => {
|
||||
@@ -249,25 +310,50 @@ export const useChatSessions = ({ chatAccounts, selectedAccount, realtimeEnabled
|
||||
|
||||
isLoadingContacts.value = true
|
||||
contactsError.value = ''
|
||||
const trace = createPerfTrace('chat-sessions', {
|
||||
account: String(selectedAccount.value || '').trim(),
|
||||
action: 'loadContacts'
|
||||
})
|
||||
trace.log('loadContacts:start', {
|
||||
cachedContacts: contacts.value.length
|
||||
})
|
||||
try {
|
||||
const hadLoadedAccountSnapshot = !!chatAccounts.loaded
|
||||
await chatAccounts.ensureLoaded()
|
||||
trace.log('loadContacts:accounts-ready', {
|
||||
hadLoadedAccountSnapshot,
|
||||
availableAccounts: Array.isArray(chatAccounts?.accounts) ? chatAccounts.accounts.length : 0
|
||||
})
|
||||
if (!selectedAccount.value && hadLoadedAccountSnapshot) {
|
||||
await chatAccounts.ensureLoaded({ force: true })
|
||||
trace.log('loadContacts:accounts-refreshed')
|
||||
}
|
||||
|
||||
if (!selectedAccount.value) {
|
||||
clearContactsState(chatAccounts.error || '未检测到已解密账号,请先解密数据库。')
|
||||
trace.log('loadContacts:no-account', {
|
||||
error: contactsError.value
|
||||
})
|
||||
return { usedPrefetched: false }
|
||||
}
|
||||
|
||||
await loadSessionsForSelectedAccount()
|
||||
trace.log('loadContacts:end', {
|
||||
contactCount: contacts.value.length
|
||||
})
|
||||
return { usedPrefetched: false }
|
||||
} catch (error) {
|
||||
clearContactsState(error?.message || '加载联系人失败')
|
||||
trace.log('loadContacts:error', {
|
||||
message: String(error?.message || '')
|
||||
})
|
||||
return { usedPrefetched: false }
|
||||
} finally {
|
||||
isLoadingContacts.value = false
|
||||
trace.log('loadContacts:exit', {
|
||||
loading: isLoadingContacts.value,
|
||||
error: contactsError.value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user