Files
new-markdown/docs/18-tab-keepalive.md
Muse 4a527da655 feat(editor): 标签编辑器保活,切换立即呈现(docs/18)
最近用过的 6 个标签保持挂载、隐藏而非销毁,切回零解析零序列化、各窗格
保留滚动位置;超限窗格卸载走最终回写。引用改为按标签注册表 + 活动变化
effect 统一指向;外部重载 epoch 按标签粒度、抑制闸门对所有标签生效。
EditorPane 新增就绪状态:首次打开大文件显示「正在打开文档…」加载态。
打印守卫:只出活动窗格。vitest 87 通过 + 2 跳过(新增 pane-loading 1 例)。
2026-11-14 13:06:39 +08:00

46 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 标签切换保活与加载状态(2026-11-14)
## 用户反馈
切换大文件时要等很久才能切回去,希望立即切回;至少要有加载进度/状态。
## 根因
原架构下每次切标签都销毁旧编辑器(全量序列化回写)并为新标签从 Markdown
全量解析重建编辑器。阶段 6 实测(jsdom 悲观口径):626K 字符建模 29.8s、
序列化 2.6s——大文档来回切换就是把这个成本反复付两遍。
## 改造:编辑器保活
- App 改为按标签渲染多个编辑器窗格,只有活动窗格可见,其余 `display:none`
保持挂载:切回时零解析、零序列化,立即显示;每个窗格自带滚动容器,
连滚动位置都各自保留。
- 保活上限:最近用过的 6 个标签(LRU)。超出的窗格卸载,卸载前走既有的
最终回写(syncEditorContent),内容不丢,之后再切到时按状态内容重建。
- 编辑器引用改为注册表(paneApisRef: tabId → api);onReady 只登记,
共享引用(查找/大纲跳转/源码锚点)由「活动标签变化」effect 统一指向
活动窗格,后台窗格就绪/卸载不会再冲掉活动窗格的引用。
- 外部重载(reloadTabFromDisk)的 epoch 重挂改为按标签粒度(paneEpochs),
且闸门(抑制卸载回写)对所有标签生效——保活后非活动标签也可能正挂载,
旧实现只处理活动标签会漏。退出源码模式的重建同理改为按标签 bump。
- 状态栏光标只接受活动窗格的回调,后台窗格不再干扰。
## 加载状态
- EditorPane 新增就绪状态:编辑器 create() 完成前在窗格内显示
「正在打开文档…」+ 旋转指示(.pane-loading),就绪即撤下。
首次打开大文件时标签立刻出现、窗格明确处于加载中,不再是无反馈的卡住。
解析是单线程同步计算,做不了真实百分比进度,用明确的加载态代替。
## 打印
@media print 增加守卫:.tab-pane 打印时隐藏、仅 .active 出纸,
避免保活窗格被通用 display:block 规则一起打出来。
## 验证
- tsc 0 错误;vitest 87 通过 + 2 跳过(新增 tests/pane-loading.test.tsx:
创建未完成时显示加载提示、完成后撤下并回传就绪 API);构建通过。
- 待真机验:两个大文档来回切换应立即呈现;首次打开大文档有加载态;
外部修改重载、源码模式进出、打印只出当前文档。