mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-11-13 17:43:23 +00:00
64 lines
3.6 KiB
Markdown
64 lines
3.6 KiB
Markdown
# Bootstrap Optimization(现状)
|
||
|
||
本文记录 **已经落地** 的 bootstrap / 启动阶段优化中,与“冷启动内存基线”强相关的部分实现快照。
|
||
|
||
> 完整的分阶段启动(Shell/Core/Full/APP_READY)链路请看:`docs/CurrentState/StartupOptimization.md`。
|
||
|
||
## TokenCache(Chat Completions)避免 cold-start whole-load
|
||
|
||
### 解决的问题
|
||
|
||
历史实现会在 `initTokenizers()` 中把 IndexedDB 里的 `tokenCache`(整库大对象)一次性读入 JS 内存,导致移动端冷启动常驻集膨胀。
|
||
|
||
### 当前实现(契约)
|
||
|
||
- **存储分区**:不再使用整库 key `tokenCache`,改为按 chat 分区持久化 `tokenCache:${chatId}`。
|
||
- **启动不加载**:`loadTokenCache()` 只做 legacy key 清理(删除 `tokenCache`),不再读取整库对象。
|
||
- **只常驻当前桶**:内存只持有“当前 chat 的一个桶”(`tokenCacheState`),切换 chat 会重置到新桶并按需懒加载。
|
||
- **事件语义一致**:
|
||
- `CHAT_CHANGED`:预热当前 chat 桶(懒加载触发点)
|
||
- `CHAT_DELETED` / `GROUP_CHAT_DELETED`:删除对应 `tokenCache:${chatId}`,避免磁盘堆积
|
||
- **写回策略**:`saveTokenCache()` 仅 flush 当前 chat 桶(dirty 才写回),不再整库写回。
|
||
|
||
### 兼容性边界
|
||
|
||
- cache 是性能优化,不影响 token 计数正确性;升级后旧整库缓存会被清理,短期缓存会重新变冷(可接受的 tradeoff)。
|
||
|
||
### 关键代码位置
|
||
|
||
- `src/scripts/tokenizers.js`:`loadTokenCache()` / `saveTokenCache()` / `resetTokenCache()` / `tokenCacheState` / `initTokenizers()` 事件挂载
|
||
|
||
---
|
||
|
||
## ItemizedPrompts(Prompt Inspector)避免 chat-open whole-load
|
||
|
||
### 解决的问题
|
||
|
||
历史实现会在打开聊天时执行 `loadItemizedPrompts(getCurrentChatId())`,并从 IndexedDB 一次性加载 `chatId -> itemizedPrompts[]` 整包数组。
|
||
|
||
该数组的单条 record 内含大量长字符串(`rawPrompt/finalPrompt/worldInfo/...`),体积通常远大于聊天正文,导致移动端 WebView renderer 常驻集显著膨胀。
|
||
|
||
### 当前实现(契约)
|
||
|
||
- **存储形态(Index + Record)**:
|
||
- Index:`tt_prompts_index:${chatId}` → `Array<{ mesId, recordId }>`
|
||
- Record:`tt_prompts_record:${chatId}:${recordId}` → 单条 prompt artifacts(原 record 全量)
|
||
- **打开聊天只加载 Index**:`loadItemizedPrompts(chatId)` 仅恢复 `mesId -> recordId` 映射,不加载任何 record。
|
||
- **点击才加载 Record**:`.mes_prompt` 点击后,`promptItemize()` 按 `mesId` 懒加载对应 record(以及可选的上一条 record 用于 diff)并渲染 Inspector。
|
||
- **生成链路不再常驻 records**:生成结束写入 record + 更新 index,不再把 record `push` 到全局数组里常驻。
|
||
- **消息编辑语义保持**:
|
||
- `swapItemizedPrompts()`:仅交换 index 的 `mesId` 映射
|
||
- `deleteItemizedPromptForMessage()`:按上游语义 shift 后续 `mesId`,并删除被删除消息的 record
|
||
- **删除/清理覆盖完整**:
|
||
- chat 删除会清理 Index + Records(不留磁盘残留)
|
||
- `clearPrompts` 会清空整个实例
|
||
|
||
### 兼容性边界
|
||
|
||
- 仍复用 `localforage` 实例名 `SillyTavern_Prompts`,保证与上游/生态对存储实例名的假设一致。
|
||
- legacy 格式(`chatId -> array`)在首次进入该 chat 且 index 不存在时,会被迁移为 Index + Records 并删除旧 key(一次性成本,后续打开聊天不再 whole-load)。
|
||
|
||
### 关键代码位置
|
||
|
||
- `src/scripts/itemized-prompts.js`:Index/Record keys、加载/迁移、Inspector 懒加载、swap/delete 语义
|
||
- `src/script.js`:生成写入、按钮显示(index presence)
|