Skip to content

Commit 1fc534b

Browse files
committed
chore: Merge branch 'dev'
2 parents abda048 + c7e72cd commit 1fc534b

File tree

76 files changed

+5109
-323
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+5109
-323
lines changed

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ src/renderer/src/components/ui/*
2222
.vscode
2323
electron.vite.config.ts
2424
*.md
25+
scripts/*
Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
# DeepChat 事件通讯与Store刷新性能分析报告
2+
3+
## 概述
4+
5+
本报告分析了 DeepChat 项目中 main 到 renderer 进程的事件通讯机制和 Pinia store 的刷新逻辑,识别了性能瓶颈并提出了相应的优化建议。
6+
7+
## 架构概览
8+
9+
### 通讯架构
10+
```
11+
Main Process Renderer Process
12+
↓ ↑
13+
EventBus ←→ Presenter → IPC ←→ Preload → usePresenter
14+
↓ ↑
15+
└─────→ sendToRenderer ────→ ipcRenderer.on
16+
```
17+
18+
### 核心组件
19+
1. **EventBus (`src/main/eventbus.ts`)**: 主进程事件协调中心
20+
2. **IPC Bridge (`src/preload/index.ts`)**: 安全的进程间通讯桥梁
21+
3. **usePresenter (`src/renderer/src/composables/usePresenter.ts`)**: 渲染进程调用主进程的代理
22+
4. **Pinia Stores**: 渲染进程状态管理
23+
24+
## 性能问题分析
25+
26+
### 1. 频繁的全量刷新
27+
28+
#### 问题描述
29+
在多个 store 中发现频繁调用全量刷新方法:
30+
31+
- **settings.ts**: `refreshAllModels()` 被频繁调用
32+
- **chat.ts**: 每次消息更新都会触发完整的消息列表刷新
33+
- **mcp.ts**: 服务器状态变化时重新加载所有工具
34+
35+
#### 具体表现
36+
```typescript
37+
// settings.ts:612 - 过于频繁的全量刷新
38+
window.electron.ipcRenderer.on(CONFIG_EVENTS.PROVIDER_CHANGED, async () => {
39+
providers.value = await configP.getProviders()
40+
await refreshAllModels() // 全量刷新所有模型
41+
})
42+
43+
// settings.ts:567 - 未优化的节流配置
44+
const refreshAllModels = useThrottleFn(_refreshAllModelsInternal, 1000, true, false)
45+
```
46+
47+
#### 性能影响
48+
- 网络请求密集:每次刷新可能触发多个 Provider API 调用
49+
- UI 渲染阻塞:大量数据更新导致界面卡顿
50+
- 内存占用增加:频繁的数据克隆和序列化
51+
52+
### 2. 低效的事件监听器管理
53+
54+
#### 问题描述
55+
事件监听器注册缺乏生命周期管理:
56+
57+
```typescript
58+
// chat.ts:1076 - 缺少清理逻辑
59+
const setupEventListeners = () => {
60+
window.electron.ipcRenderer.on(CONVERSATION_EVENTS.LIST_UPDATED, (_, data) => {
61+
// 处理逻辑
62+
})
63+
// 没有对应的 removeListener 逻辑
64+
}
65+
```
66+
67+
#### 性能影响
68+
- 内存泄漏:监听器累积导致内存使用持续增长
69+
- 重复执行:同一事件可能被多个监听器处理
70+
- 调试困难:事件流追踪复杂
71+
72+
### 3. 同步阻塞操作
73+
74+
#### 问题描述
75+
preload 脚本中使用同步 IPC 调用:
76+
77+
```typescript
78+
// preload/index.ts:24,31 - 同步调用阻塞渲染进程
79+
cachedWindowId = ipcRenderer.sendSync('get-window-id')
80+
cachedWebContentsId = ipcRenderer.sendSync('get-web-contents-id')
81+
```
82+
83+
#### 性能影响
84+
- 渲染进程阻塞:同步调用会暂停 UI 响应
85+
- 启动延迟:应用初始化过程变慢
86+
87+
### 4. 过度的序列化开销
88+
89+
#### 问题描述
90+
usePresenter 中过度保护性的序列化:
91+
92+
```typescript
93+
// usePresenter.ts:64 - 每次调用都进行深度序列化
94+
const rawPayloads = payloads.map((e) => safeSerialize(toRaw(e)))
95+
```
96+
97+
#### 性能影响
98+
- CPU 占用:复杂对象的深度序列化消耗大量计算资源
99+
- 内存开销:创建大量临时对象
100+
- 调用延迟:每次 IPC 调用都有额外开销
101+
102+
### 5. 状态管理冗余
103+
104+
#### 问题描述
105+
多个 store 之间存在状态冗余和重复计算:
106+
107+
```typescript
108+
// chat.ts 中的复杂状态管理
109+
const threadsWorkingStatusMap = ref<Map<number, Map<string, WorkingStatus>>>(new Map())
110+
const generatingMessagesCacheMap = ref<Map<number, Map<string, { message: AssistantMessage | UserMessage; threadId: string }>>>(new Map())
111+
```
112+
113+
#### 性能影响
114+
- 内存占用:重复存储相似数据
115+
- 同步复杂:多个状态源需要保持一致性
116+
- 更新延迟:状态变更需要在多处同步
117+
118+
## 优化建议
119+
120+
### 1. 增量更新策略
121+
122+
#### 实现方案
123+
```typescript
124+
// 替换全量刷新为增量更新
125+
const updateModelStatus = (providerId: string, modelId: string, enabled: boolean) => {
126+
// 只更新特定模型状态,而非重新加载所有模型
127+
const providerIndex = enabledModels.value.findIndex(p => p.providerId === providerId)
128+
if (providerIndex !== -1) {
129+
const modelIndex = enabledModels.value[providerIndex].models.findIndex(m => m.id === modelId)
130+
if (modelIndex !== -1) {
131+
enabledModels.value[providerIndex].models[modelIndex].enabled = enabled
132+
}
133+
}
134+
}
135+
```
136+
137+
#### 预期收益
138+
- 减少 50% 的 API 调用
139+
- 降低 70% 的 UI 重渲染
140+
- 提升响应速度 3-5 倍
141+
142+
### 2. 事件监听器生命周期管理
143+
144+
#### 实现方案
145+
```typescript
146+
// 添加监听器清理机制
147+
const useEventCleanup = () => {
148+
const listeners = new Set<() => void>()
149+
150+
const addListener = (event: string, handler: Function) => {
151+
window.electron.ipcRenderer.on(event, handler)
152+
listeners.add(() => window.electron.ipcRenderer.off(event, handler))
153+
}
154+
155+
const cleanup = () => {
156+
listeners.forEach(remove => remove())
157+
listeners.clear()
158+
}
159+
160+
onUnmounted(cleanup)
161+
162+
return { addListener, cleanup }
163+
}
164+
```
165+
166+
#### 预期收益
167+
- 消除内存泄漏
168+
- 减少事件处理冲突
169+
- 提升应用稳定性
170+
171+
### 3. 异步化改造
172+
173+
#### 实现方案
174+
```typescript
175+
// 将同步调用改为异步
176+
const getWebContentsId = async (): Promise<number> => {
177+
if (cachedWebContentsId !== null) {
178+
return cachedWebContentsId
179+
}
180+
181+
try {
182+
cachedWebContentsId = await window.electron.ipcRenderer.invoke('get-web-contents-id')
183+
return cachedWebContentsId
184+
} catch (error) {
185+
console.warn('Failed to get webContentsId:', error)
186+
return -1
187+
}
188+
}
189+
```
190+
191+
#### 预期收益
192+
- 消除 UI 阻塞
193+
- 改善用户体验
194+
- 提升应用启动速度
195+
196+
### 4. 智能序列化优化
197+
198+
#### 实现方案
199+
```typescript
200+
// 实现智能序列化策略
201+
const smartSerialize = (obj: unknown): unknown => {
202+
// 对于简单类型直接返回
203+
if (obj === null || typeof obj !== 'object') {
204+
return obj
205+
}
206+
207+
// 检查对象大小,小对象直接序列化
208+
if (getObjectSize(obj) < 1024) {
209+
return safeSerialize(obj)
210+
}
211+
212+
// 大对象进行引用传递
213+
return createObjectReference(obj)
214+
}
215+
```
216+
217+
#### 预期收益
218+
- 减少 60% 的序列化开销
219+
- 降低内存使用
220+
- 提升 IPC 调用性能
221+
222+
### 5. 状态管理优化
223+
224+
#### 实现方案
225+
```typescript
226+
// 统一状态管理
227+
const useGlobalState = () => {
228+
const centralStore = useCentralStore()
229+
230+
// 使用计算属性避免重复状态
231+
const threadStatus = computed(() =>
232+
centralStore.getThreadStatus(activeThreadId.value)
233+
)
234+
235+
// 使用 reactive 替代多层嵌套的 ref
236+
const statusMap = reactive(new Map<string, WorkingStatus>())
237+
238+
return { threadStatus, statusMap }
239+
}
240+
```
241+
242+
#### 预期收益
243+
- 减少 40% 的内存使用
244+
- 简化状态同步逻辑
245+
- 提升维护性
246+
247+
## 性能监控建议
248+
249+
### 1. 关键指标监控
250+
- IPC 调用频率和延迟
251+
- 事件监听器数量
252+
- Store 状态更新频率
253+
- 内存使用趋势
254+
255+
### 2. 性能测试用例
256+
- 大量消息场景下的渲染性能
257+
- 多个 Provider 同时更新的响应时间
258+
- 长时间运行的内存稳定性
259+
260+
### 3. 开发工具集成
261+
- 添加 IPC 调用日志(已有 VITE_LOG_IPC_CALL)
262+
- 实现事件流可视化
263+
- 集成性能分析器
264+
265+
## 实施优先级
266+
267+
### 高优先级(立即实施)
268+
1. 异步化 preload 中的同步调用
269+
2. 实现事件监听器清理机制
270+
3. 优化 settings store 的全量刷新逻辑
271+
272+
### 中优先级(短期实施)
273+
1. 实现增量更新策略
274+
2. 优化序列化机制
275+
3. 添加性能监控
276+
277+
### 低优先级(长期优化)
278+
1. 重构状态管理架构
279+
2. 实现更细粒度的事件系统
280+
3. 添加自动化性能测试
281+
282+
## 总结
283+
284+
DeepChat 的事件通讯和状态管理系统总体架构合理,但在性能优化方面还有很大提升空间。通过实施上述优化建议,预计可以显著提升应用的响应速度、降低内存使用并改善用户体验。建议按照优先级逐步实施,并在每个阶段进行性能测试验证优化效果。

electron.vite.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default defineConfig({
1313
plugins: [
1414
externalizeDepsPlugin({
1515
exclude: ['mermaid', 'dompurify']
16-
})
16+
}),
1717
],
1818
resolve: {
1919
alias: {
@@ -60,6 +60,7 @@ export default defineConfig({
6060
},
6161
css: {
6262
postcss: {
63+
// @ts-ignore
6364
plugins: [tailwind(), autoprefixer()]
6465
}
6566
},

0 commit comments

Comments
 (0)