update at 2025-10-14 21:52:11

This commit is contained in:
douboer
2025-10-14 21:52:11 +08:00
parent ac3ed480ab
commit 4f5eea604e
40 changed files with 15231 additions and 126 deletions

374
PERFORMANCE_ANALYSIS.md Normal file
View File

@@ -0,0 +1,374 @@
# 性能追踪分析指南
## 已添加的性能追踪点
### 1. 总体流程追踪
```
用户发送消息
[chatStore.sendMessageStream]
[chatService.sendMessageStream] ⏱️ callModelStream总耗时
├─ [chatService.callModel] ⏱️ callModel总耗时
│ ├─ 准备消息 ⏱️ 准备消息耗时
│ ├─ 服务匹配
│ ├─ [modelServiceManager.sendChatRequest] ⏱️ 请求耗时
│ │ ├─ 准备 ⏱️ 准备耗时
│ │ └─ [makeChatRequest] ⏱️ makeChatRequest总耗时
│ │ ├─ 构建请求 ⏱️ 构建请求耗时
│ │ ├─ 网络请求 ⏱️ 网络请求耗时 ← 通常最慢的部分
│ │ └─ 解析响应 ⏱️ 解析响应耗时
│ └─ 解析响应 ⏱️ 解析响应耗时
└─ 模拟流式输出 ⏱️ 模拟流式输出耗时
```
### 2. 关键性能指标
#### 控制台日志格式
```javascript
// 开始
⏱️ [callModelStream] 开始流式处理
⏱️ [callModel] 开始处理 {model: "xxx", 对话消息数: 5}
⏱️ [callModel] 准备消息耗时: 0.50 ms 处理后消息数: 5
⏱️ [sendChatRequest] 开始请求 {serviceId: "xxx", model: "xxx", messages数量: 5}
// 网络请求阶段 (通常最慢)
⏱️ [sendChatRequest] 准备耗时: 0.10 ms
⏱️ [makeChatRequest] 构建请求耗时: 0.20 ms
🔍 [makeChatRequest] 请求体大小: 1024 字节
⏱️ [makeChatRequest] 网络请求耗时: 2500.00 ms 关键指标!
🔍 [makeChatRequest] 响应状态: 200 OK
// 解析阶段
⏱️ [makeChatRequest] 解析响应耗时: 5.00 ms
⏱️ [makeChatRequest] makeChatRequest总耗时: 2505.50 ms
⏱️ [sendChatRequest] 请求耗时: 2505.60 ms
⏱️ [sendChatRequest] 总耗时: 2505.70 ms
⏱️ [callModel] 服务调用耗时: 2505.80 ms
⏱️ [callModel] 解析响应耗时: 0.30 ms
⏱️ [callModel] callModel总耗时: 2507.00 ms
// 流式输出阶段
⏱️ [callModelStream] callModel耗时: 2507.10 ms
⏱️ [callModelStream] 模拟流式输出耗时: 1800.00 ms
⏱️ [callModelStream] 输出块数: 60 总字符数: 300
⏱️ [callModelStream] callModelStream总耗时: 4307.10 ms
```
## 性能瓶颈分析
### 常见的慢速原因
#### 1. 网络请求慢 (2000-5000ms)
**症状**:
```
⏱️ [makeChatRequest] 网络请求耗时: 3500.00 ms
```
**可能原因**:
- API服务器响应慢
- 网络延迟高
- 请求体太大
- API配额限制
**解决方案**:
```javascript
// 1. 检查请求体大小
🔍 [makeChatRequest] 请求体大小: 50000 字节 // 如果>10KB需要优化
// 2. 减少上下文消息数量
const messages = conversation.messages
.filter(m => m.status === 'success')
.slice(-10) // 只保留最近10条消息
// 3. 使用CDN或更近的API端点
// 火山引擎: https://ark.cn-beijing.volces.com (北京)
// 阿里云: https://dashscope.aliyuncs.com (杭州)
```
#### 2. 模拟流式输出慢 (1000-3000ms)
**症状**:
```
⏱️ [callModelStream] 模拟流式输出耗时: 2400.00 ms
⏱️ [callModelStream] 输出块数: 80 总字符数: 400
```
**原因**:
```javascript
// 每个块延迟30ms
await new Promise(resolve => setTimeout(resolve, 30))
// 80块 × 30ms = 2400ms
```
**解决方案**:
```javascript
// 方案1: 减少延迟
await new Promise(resolve => setTimeout(resolve, 10)) // 30ms → 10ms
// 方案2: 增加块大小
const chunkSize = 10 // 5 → 10,减少块数
// 方案3: 使用真正的流式API (最佳)
// 火山引擎支持 stream: true
body = {
model,
messages,
stream: true // 启用流式
}
```
#### 3. 消息准备慢 (>100ms)
**症状**:
```
⏱️ [callModel] 准备消息耗时: 150.00 ms 处理后消息数: 1000
```
**原因**: 消息数量太多
**解决方案**:
```javascript
// 限制消息历史
const MAX_MESSAGES = 20
const messages = conversation.messages
.filter(m => m.status === 'success')
.slice(-MAX_MESSAGES) // 只保留最近20条
```
#### 4. 响应解析慢 (>100ms)
**症状**:
```
⏱️ [makeChatRequest] 解析响应耗时: 250.00 ms
```
**原因**: 响应体太大
**解决方案**:
```javascript
// 检查响应大小
console.log('响应大小:', JSON.stringify(result).length, '字节')
// 如果太大,考虑:
// 1. 限制 max_tokens
body = {
model,
messages,
max_tokens: 1000 // 限制输出长度
}
```
## 性能优化建议
### 优先级1: 启用真正的流式API
**当前实现** (假流式):
```typescript
// chatService.ts
const result = await this.callModel(conversation, model) // 等待完整响应
// 然后模拟流式输出
for (let i = 0; i < content.length; i += chunkSize) {
onChunk(chunk)
await new Promise(resolve => setTimeout(resolve, 30)) // 人工延迟
}
```
**优化后** (真流式):
```typescript
// modelServiceManager.ts - makeChatRequest
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({
model,
messages,
stream: true // ← 启用流式
})
})
// 读取流
const reader = response.body.getReader()
const decoder = new TextDecoder()
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
const lines = chunk.split('\n')
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6))
if (data.choices[0].delta?.content) {
onChunk(data.choices[0].delta.content) // 实时输出
}
}
}
}
```
**效果**:
- ❌ 当前: 等待3000ms + 模拟2000ms = **5000ms总延迟**
- ✅ 优化后: 实时流式 = **首字输出<500ms**
### 优先级2: 减少请求体大小
```typescript
// chatService.ts - callModel
const MAX_CONTEXT_MESSAGES = 10 // 最多10条上下文
const MAX_CONTENT_LENGTH = 2000 // 每条消息最多2000字符
const messages = conversation.messages
.filter(m => m.status === 'success')
.slice(-MAX_CONTEXT_MESSAGES) // 只保留最近N条
.map(m => ({
role: m.role,
content: m.content.slice(0, MAX_CONTENT_LENGTH) // 限制长度
}))
```
### 优先级3: 优化模拟流式的参数
```typescript
// chatService.ts - callModelStream
const chunkSize = 20 // 5 → 20 (增大块,减少循环)
const delay = 10 // 30 → 10 (减少延迟)
for (let i = 0; i < content.length; i += chunkSize) {
const chunk = content.slice(i, i + chunkSize)
onChunk(chunk)
await new Promise(resolve => setTimeout(resolve, delay))
}
```
**效果**:
- 字符数: 300
- 块数: 300/20 = 15块 (原来60块)
- 总延迟: 15×10 = 150ms (原来1800ms)
- **提速12倍!**
### 优先级4: 添加超时控制
```typescript
// modelServiceManager.ts - makeChatRequest
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 30000) // 30秒超时
try {
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify(body),
signal: controller.signal
})
clearTimeout(timeoutId)
// ...
} catch (error) {
clearTimeout(timeoutId)
if (error.name === 'AbortError') {
throw new Error('请求超时(30秒)')
}
throw error
}
```
## 使用方法
### 1. 打开浏览器控制台
`F12``Cmd+Option+I` (Mac)
### 2. 发送测试消息
在聊天界面输入简短消息,如 "你好"
### 3. 查看性能日志
在控制台搜索 `⏱️` 查看所有计时日志
### 4. 分析瓶颈
按照时间从大到小排序:
```
⏱️ [callModelStream] callModelStream总耗时: 4307.10 ms ← 总时间
├─ [callModel] callModel总耗时: 2507.00 ms
│ └─ [makeChatRequest] 网络请求耗时: 2500.00 ms ← 瓶颈1
└─ [callModelStream] 模拟流式输出耗时: 1800.00 ms ← 瓶颈2
```
### 5. 针对性优化
- 如果 **网络请求耗时** > 2000ms → 检查网络/API
- 如果 **模拟流式输出耗时** > 1000ms → 优化流式参数或启用真流式
- 如果 **准备消息耗时** > 100ms → 限制消息历史数量
## 预期性能指标
### 理想情况 (真流式API + 优化)
```
⏱️ [callModel] 准备消息耗时: < 10 ms
⏱️ [makeChatRequest] 构建请求耗时: < 5 ms
⏱️ [makeChatRequest] 网络请求耗时: 500-1500 ms (首字输出)
⏱️ [callModelStream] 流式输出: 实时,无额外延迟
⏱️ 总体首字延迟: < 2000 ms
```
### 当前情况 (假流式)
```
⏱️ [callModel] 准备消息耗时: 0.5-2 ms ✅
⏱️ [makeChatRequest] 构建请求耗时: 0.2-1 ms ✅
⏱️ [makeChatRequest] 网络请求耗时: 2000-5000 ms ⚠️
⏱️ [callModelStream] 模拟流式输出: 1000-3000 ms ❌
⏱️ 总体延迟: 3000-8000 ms ❌
```
## 快速诊断清单
| 问题 | 检查项 | 正常值 | 解决方案 |
|------|--------|--------|----------|
| 总体很慢 | callModelStream总耗时 | < 5000ms | 检查网络和流式 |
| 网络慢 | 网络请求耗时 | < 2000ms | 换更近的API端点 |
| 流式慢 | 模拟流式输出耗时 | < 500ms | 优化参数或启用真流式 |
| 准备慢 | 准备消息耗时 | < 10ms | 限制消息数量 |
| 解析慢 | 解析响应耗时 | < 10ms | 检查响应大小 |
## 立即可做的优化
### 快速优化1: 调整流式参数 (30秒)
编辑 `/web/src/services/chatService.ts` 第565行:
```typescript
// 原来
const chunkSize = 5
await new Promise(resolve => setTimeout(resolve, 30))
// 改为
const chunkSize = 20
await new Promise(resolve => setTimeout(resolve, 10))
```
**效果**: 流式输出速度提升 **6-12倍**
### 快速优化2: 限制消息历史 (1分钟)
编辑 `/web/src/services/chatService.ts` 第500行:
```typescript
// 原来
const messages = conversation.messages
.filter(m => m.status === 'success')
.map(m => ({ role: m.role, content: m.content }))
// 改为
const MAX_MESSAGES = 10
const messages = conversation.messages
.filter(m => m.status === 'success')
.slice(-MAX_MESSAGES) // 只保留最近10条
.map(m => ({ role: m.role, content: m.content }))
```
**效果**: 减少请求体大小,提升网络速度 **10-30%**
---
**创建时间**: 2025年10月14日
**适用版本**: mcp-client-vue v2.1+