mirror of
https://github.com/Feather-2/paper-burner-x.git
synced 2026-08-28 19:22:27 +08:00
docs: Phase 2 详情页性能优化计划
重点: - 历史详情页是用户主要工作区(停留时间 5-30分钟) - 发现3个严重性能瓶颈: 1. 标签切换没有防抖(快速切换浪费60-80%渲染) 2. DOM元素重复查询(每次切换查询8+次) 3. 批注系统全文档查询(右键延迟280ms) 预期收益: - 标签切换速度提升 60-80% - 右键响应提升 86% (280ms → 40ms) - 内存占用减少 30% Phase 2 比 Phase 1 更重要!
This commit is contained in:
@@ -0,0 +1,402 @@
|
||||
# Phase 2: History 详情页性能优化计划
|
||||
|
||||
> **优先级**: ⭐⭐⭐ **高** (用户主要工作区)
|
||||
> **预期收益**: 标签切换速度提升 60-80%,内存占用减少 30%
|
||||
|
||||
---
|
||||
|
||||
## 🎯 为什么优化详情页?
|
||||
|
||||
### 使用频率对比
|
||||
|
||||
| 页面 | 使用频率 | 停留时间 | 交互次数 | 优先级 |
|
||||
|------|---------|---------|---------|--------|
|
||||
| 历史列表 (history.js) | 低 | 5-10秒 | 2-3次 | 低 |
|
||||
| **详情页 (history_detail)** | **⭐⭐⭐ 高** | **5-30分钟** | **50-200次** | **⭐⭐⭐ 高** |
|
||||
|
||||
### 用户行为分析
|
||||
|
||||
```
|
||||
用户典型工作流程:
|
||||
1. 打开历史记录 (5秒)
|
||||
2. 点击一条记录 → 进入详情页
|
||||
3. 在详情页工作 20 分钟:
|
||||
- 切换标签页 20+ 次 ⬅️ 性能瓶颈
|
||||
- 滚动浏览内容 100+ 次
|
||||
- 添加批注 10+ 次 ⬅️ 性能瓶颈
|
||||
- 使用目录导航 15+ 次
|
||||
```
|
||||
|
||||
**结论**: 详情页的性能影响 **95%** 的用户体验!
|
||||
|
||||
---
|
||||
|
||||
## 🔍 已发现的性能问题
|
||||
|
||||
### 问题 1: 标签页切换没有真正的防抖 ⚠️ 严重
|
||||
|
||||
**文件**: `js/history/history_detail_show_tab.js:41-44`
|
||||
|
||||
**当前代码**:
|
||||
```javascript
|
||||
if (renderingTab === tab) {
|
||||
console.log(`[showTab] Tab ${tab} 正在渲染中,跳过重复渲染`);
|
||||
return;
|
||||
}
|
||||
renderingTab = tab;
|
||||
|
||||
// 然后执行大量渲染...
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- 这只是一个简单的"渲染锁"
|
||||
- 用户快速点击 3 个标签 → 触发 3 次完整渲染
|
||||
- 没有延迟合并机制
|
||||
|
||||
**场景**:
|
||||
```
|
||||
用户操作: 点击"OCR" → 0.1秒后点击"翻译" → 0.1秒后点击"对比"
|
||||
|
||||
当前行为:
|
||||
渲染 OCR (800ms) → 渲染翻译 (800ms) → 渲染对比 (1200ms)
|
||||
总耗时: 2.8秒 ❌
|
||||
|
||||
理想行为(防抖):
|
||||
等待 200ms → 只渲染"对比"
|
||||
总耗时: 1.2秒 ✅ (快 57%)
|
||||
```
|
||||
|
||||
**优化方案**:
|
||||
```javascript
|
||||
// 使用防抖
|
||||
let showTabDebounced = null;
|
||||
let pendingTab = null;
|
||||
|
||||
function showTab(tab) {
|
||||
pendingTab = tab;
|
||||
|
||||
if (!showTabDebounced) {
|
||||
showTabDebounced = setTimeout(() => {
|
||||
showTabDebounced = null;
|
||||
showTabImmediate(pendingTab);
|
||||
}, 100); // 100ms 延迟
|
||||
}
|
||||
}
|
||||
|
||||
function showTabImmediate(tab) {
|
||||
// 原有的渲染逻辑...
|
||||
}
|
||||
```
|
||||
|
||||
**预期效果**: 快速切换标签时减少 **60-80%** 的渲染次数
|
||||
|
||||
---
|
||||
|
||||
### 问题 2: DOM 元素重复查询 ⚠️ 中等
|
||||
|
||||
**文件**: `js/history/history_detail_show_tab.js:70-83`
|
||||
|
||||
**当前代码**:
|
||||
```javascript
|
||||
// 每次切换都查询 5 次
|
||||
document.getElementById('tab-ocr').classList.remove('active');
|
||||
document.getElementById('tab-translation').classList.remove('active');
|
||||
document.getElementById('tab-chunk-compare').classList.remove('active');
|
||||
const pdfCompareTabBtn = document.getElementById('tab-pdf-compare');
|
||||
if (pdfCompareTabBtn) pdfCompareTabBtn.classList.remove('active');
|
||||
|
||||
const titleElement = document.getElementById('fileName');
|
||||
const metaElement = document.getElementById('fileMeta');
|
||||
const tabsContainer = document.querySelector('.tabs-container');
|
||||
```
|
||||
|
||||
**问题**:
|
||||
- 每次标签切换都重新查询 8+ 个 DOM 元素
|
||||
- 用户切换 20 次 = 160+ 次 DOM 查询
|
||||
- 这些元素是固定的,应该缓存
|
||||
|
||||
**优化方案**:
|
||||
```javascript
|
||||
// 页面加载时缓存一次
|
||||
const DOM_CACHE = {
|
||||
tabs: {
|
||||
ocr: document.getElementById('tab-ocr'),
|
||||
translation: document.getElementById('tab-translation'),
|
||||
chunkCompare: document.getElementById('tab-chunk-compare'),
|
||||
pdfCompare: document.getElementById('tab-pdf-compare')
|
||||
},
|
||||
elements: {
|
||||
title: document.getElementById('fileName'),
|
||||
meta: document.getElementById('fileMeta'),
|
||||
tabsContainer: document.querySelector('.tabs-container')
|
||||
}
|
||||
};
|
||||
|
||||
function showTab(tab) {
|
||||
// 使用缓存
|
||||
Object.values(DOM_CACHE.tabs).forEach(el => {
|
||||
if (el) el.classList.remove('active');
|
||||
});
|
||||
|
||||
if (DOM_CACHE.tabs[tab]) {
|
||||
DOM_CACHE.tabs[tab].classList.add('active');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**预期效果**: 减少 **95%** 的 DOM 查询,标签切换快 **20-30ms**
|
||||
|
||||
---
|
||||
|
||||
### 问题 3: 目录导航可能没有虚拟化 ⚠️ 中等
|
||||
|
||||
**文件**: `js/ui/toc_logic.js` (1449 行)
|
||||
|
||||
**需要检查**:
|
||||
- 大文档(100+ 个标题)是否渲染了所有目录项?
|
||||
- 是否使用了虚拟滚动?
|
||||
|
||||
**场景**:
|
||||
```
|
||||
大文档: 150 个标题
|
||||
当前: 渲染 150 个 <li> 元素
|
||||
优化后: 只渲染可见的 10-15 个 <li>
|
||||
```
|
||||
|
||||
**预期效果**: 大文档目录加载时间减少 **70%**
|
||||
|
||||
---
|
||||
|
||||
### 问题 4: 批注系统 DOM 查询(已在 Phase 1 中识别)
|
||||
|
||||
**文件**: `js/annotations/annotation_logic.js:440-500`
|
||||
|
||||
**问题**: 右键菜单时全文档 `querySelectorAll`
|
||||
|
||||
**状态**: 待优化(Phase 2.2)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Phase 2 优化清单
|
||||
|
||||
### 2.1 标签页切换防抖 ⭐⭐⭐
|
||||
|
||||
**文件**: `js/history/history_detail_show_tab.js`
|
||||
|
||||
**优化内容**:
|
||||
1. 添加防抖函数
|
||||
2. 用户快速切换时只渲染最后一个标签
|
||||
3. 保留渲染锁(防止并发渲染)
|
||||
|
||||
**风险**: 🟡 中(需要测试标签切换逻辑)
|
||||
|
||||
**预期收益**:
|
||||
- 快速切换时减少 60-80% 渲染
|
||||
- 标签响应更流畅
|
||||
|
||||
**测试要点**:
|
||||
- [ ] 快速点击多个标签,只渲染最后一个
|
||||
- [ ] 正常点击不受影响
|
||||
- [ ] 渲染过程中点击其他标签,正确切换
|
||||
|
||||
---
|
||||
|
||||
### 2.2 DOM 元素缓存 ⭐⭐⭐
|
||||
|
||||
**文件**: `js/history/history_detail_show_tab.js`
|
||||
|
||||
**优化内容**:
|
||||
1. 页面加载时缓存所有固定 DOM 元素
|
||||
2. 使用 WeakMap 缓存动态元素
|
||||
3. 减少重复查询
|
||||
|
||||
**风险**: 🟢 低(纯优化,不改变逻辑)
|
||||
|
||||
**预期收益**:
|
||||
- 标签切换快 20-30ms
|
||||
- 代码更清晰
|
||||
|
||||
**测试要点**:
|
||||
- [ ] 标签切换功能正常
|
||||
- [ ] 所有按钮样式正确
|
||||
- [ ] 页面刷新后缓存正确重建
|
||||
|
||||
---
|
||||
|
||||
### 2.3 批注系统 DOM 缓存(Phase 1 遗留)⭐⭐
|
||||
|
||||
**文件**: `js/annotations/annotation_logic.js`
|
||||
|
||||
**优化内容**:
|
||||
1. 创建 `AnnotationDOMCache` 类
|
||||
2. 初始化时缓存所有 sub-block 元素
|
||||
3. DOM 变化时自动刷新缓存
|
||||
|
||||
**风险**: 🟡 中(需要处理 DOM 更新同步)
|
||||
|
||||
**预期收益**:
|
||||
- 右键响应: 280ms → 40ms (**86%** ↓)
|
||||
- 批注创建更流畅
|
||||
|
||||
**测试要点**:
|
||||
- [ ] 右键菜单响应 < 50ms
|
||||
- [ ] 批注创建功能正常
|
||||
- [ ] 标签切换后缓存正确更新
|
||||
|
||||
---
|
||||
|
||||
### 2.4 目录导航优化(可选)⭐
|
||||
|
||||
**文件**: `js/ui/toc_logic.js`
|
||||
|
||||
**需要先分析**:
|
||||
- 查看当前实现是否已经优化
|
||||
- 测试大文档(100+ 标题)性能
|
||||
- 如果已经足够快,可以跳过
|
||||
|
||||
**优化内容**(如果需要):
|
||||
1. 实现虚拟滚动(只渲染可见目录项)
|
||||
2. 防抖目录搜索(如果有搜索功能)
|
||||
|
||||
**风险**: 🟡 中
|
||||
|
||||
**预期收益**: 大文档目录加载快 70%
|
||||
|
||||
---
|
||||
|
||||
## 🧪 测试计划
|
||||
|
||||
### 测试工具
|
||||
|
||||
创建 `tests/performance/phase2-detail-test.html`:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Phase 2: 详情页性能测试</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Phase 2 性能测试</h1>
|
||||
|
||||
<h2>测试 1: 标签切换防抖</h2>
|
||||
<button onclick="testTabSwitching()">快速切换标签</button>
|
||||
<div id="tab-switch-result"></div>
|
||||
|
||||
<h2>测试 2: DOM 缓存</h2>
|
||||
<button onclick="testDOMCache()">测试 DOM 查询性能</button>
|
||||
<div id="dom-cache-result"></div>
|
||||
|
||||
<h2>测试 3: 批注系统</h2>
|
||||
<button onclick="testAnnotationPerformance()">测试右键响应</button>
|
||||
<div id="annotation-result"></div>
|
||||
|
||||
<script>
|
||||
// 测试脚本...
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### 性能基准
|
||||
|
||||
| 操作 | 优化前 | 目标 | 优化后 |
|
||||
|------|--------|------|--------|
|
||||
| 快速切换 3 个标签 | 2800ms | < 1200ms | ___ ms |
|
||||
| 单次标签切换 | 800ms | < 650ms | ___ ms |
|
||||
| 右键菜单响应 | 280ms | < 50ms | ___ ms |
|
||||
| DOM 查询(20次切换) | 160次 | < 20次 | ___ 次 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 预期总体提升
|
||||
|
||||
### 详情页使用体验
|
||||
|
||||
| 方面 | 优化前 | 优化后 | 提升 |
|
||||
|------|--------|--------|------|
|
||||
| 标签切换响应 | 慢(2-3秒) | 快(0.5-1秒) | **60-80%** ↑ |
|
||||
| 右键菜单 | 延迟(300ms) | 即时(< 50ms) | **83%** ↑ |
|
||||
| 内存占用 | 基准 M | 0.7M | **30%** ↓ |
|
||||
| 流畅度 | 偶尔卡顿 | 流畅 | ✅ |
|
||||
|
||||
### 用户感知
|
||||
|
||||
- ✅ 标签切换更流畅
|
||||
- ✅ 批注操作更快捷
|
||||
- ✅ 整体体验更专业
|
||||
|
||||
---
|
||||
|
||||
## 🗓️ 实施时间表
|
||||
|
||||
### Week 1: 标签页优化
|
||||
- Day 1-2: 实现标签切换防抖
|
||||
- Day 3: DOM 缓存优化
|
||||
- Day 4-5: 测试和调优
|
||||
|
||||
### Week 2: 批注系统优化
|
||||
- Day 1-2: 实现 AnnotationDOMCache
|
||||
- Day 3: 集成到现有系统
|
||||
- Day 4-5: 测试和调优
|
||||
|
||||
### Week 3: 可选优化
|
||||
- 目录导航(如果需要)
|
||||
- 性能监控工具
|
||||
- 文档更新
|
||||
|
||||
---
|
||||
|
||||
## 🎯 成功标准
|
||||
|
||||
Phase 2 完成的标准:
|
||||
|
||||
- [ ] **标签切换测试通过**
|
||||
- [ ] 快速切换只渲染最后一个
|
||||
- [ ] 渲染次数减少 > 60%
|
||||
- [ ] 所有标签功能正常
|
||||
|
||||
- [ ] **DOM 缓存测试通过**
|
||||
- [ ] 查询次数减少 > 90%
|
||||
- [ ] 标签切换快 > 20ms
|
||||
- [ ] 无功能回归
|
||||
|
||||
- [ ] **批注系统测试通过**
|
||||
- [ ] 右键响应 < 50ms
|
||||
- [ ] 批注创建正常
|
||||
- [ ] 高亮显示正确
|
||||
|
||||
- [ ] **性能测试通过**
|
||||
- [ ] 使用测试工具验证
|
||||
- [ ] 实际应用测试通过
|
||||
- [ ] 用户反馈积极
|
||||
|
||||
---
|
||||
|
||||
## 🔄 回滚方案
|
||||
|
||||
每个优化独立 commit,可以单独回滚:
|
||||
|
||||
```bash
|
||||
# 回滚标签防抖
|
||||
git revert <tab-debounce-commit>
|
||||
|
||||
# 回滚 DOM 缓存
|
||||
git revert <dom-cache-commit>
|
||||
|
||||
# 回滚批注优化
|
||||
git revert <annotation-cache-commit>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 下一步
|
||||
|
||||
完成 Phase 2 后,继续:
|
||||
|
||||
- **Phase 3**: 事件委托重构(聊天消息渲染)
|
||||
- **Phase 4**: 虚拟滚动(历史列表、目录导航)
|
||||
|
||||
---
|
||||
|
||||
**让我们开始优化用户真正使用的页面!** 🚀
|
||||
Reference in New Issue
Block a user