7.2 KiB
7.2 KiB
阶段 6 报告:体验与性能
完成日期:2026-11-13。本阶段交付专注/打字机模式、文档内查找替换、工作区全文搜索、快捷键自定义中心、多窗口与大文档性能实测。
1. 实现内容
专注模式与打字机模式(视图菜单开关,随偏好持久化)
- 专注模式:自研 ProseMirror 装饰插件(
createFocusDimPlugin)——选区/文档变化时给「非当前顶层块」加节点装饰类focus-dim(CSS 透明度 0.32 + 0.25s 过渡);选区所在顶层块保持全亮。装饰是纯呈现层,不入模型、不入撤销历史。开关切换时经插件 meta 立即重算,编辑器创建完成后也会按当前开关状态应用一次。 - 打字机模式:EditorPane 的光标回调里用
coordsAtPos计算光标行位置,当其偏离编辑区垂直中央超过 6px 时平滑滚动使光标行回到中央;仅滚动容器操作,不改文档。
文档内查找替换(编辑菜单/Ctrl+F、Ctrl+H)
- 引擎:
src/editor/search.ts把文档拍平成「字符 → 文档位置」索引(块间放分隔符),在此之上做明文/正则匹配——命中可跨文本节点(如粗体边界)精确映射回文档位置,跨块命中自动跳过(避免替换合并段落)。选项:区分大小写、全词匹配(ASCII 词边界)、正则(非法正则给出中文错误提示),命中上限 5000。 - 渲染模式走 ProseMirror 事务(选中命中并滚动到可见处;替换为单事务
insertText,可撤销;全部替换倒序单事务完成);源码模式在 CodeMirror 文档文本上复用同一套语义实现偏移版查找/替换。 - UI:右上角浮动 FindBar(查找/替换两行可折叠、命中计数
当前 / 总数、Enter 下一个/Shift+Enter 上一个、Esc 关闭);打开时自动带入编辑器选区文本作为查询词;切换标签/模式时对新上下文自动重算;同一文档的编辑会经替换后自动刷新命中。
工作区全文搜索(侧边栏第三页签「搜索」)
- Rust 纯逻辑模块
search.rs:递归扫描工作区内的.md/.markdown/.txt(跳过隐藏目录与 node_modules,单文件上限 2MB),逐行包含匹配,返回行号 + 片段(≤160 字)。保护上限:有命中的文件 ≤300、单文件命中 ≤20。命令workspace_search转发;逻辑已用独立 crate 对临时目录树实跑断言(大小写敏感/不敏感、跳过隐藏目录与图片、空查询)。 - 前端页签含查询框、区分大小写开关、结果按文件分组(文件名 + 行号 + 片段);点击任一命中在主窗口打开文件并自动打开查找条定位该查询词。Web 降级模式与未打开文件夹时给出明确提示。
快捷键自定义中心(帮助 → 快捷键设置…)
- 应用级快捷键从 App 的硬编码分支重构为注册表(
src/utils/shortcuts.ts):22 个动作(新建/打开/保存/另存为/关闭标签/查找/替换/侧边栏/链接/图片/表格/引用/代码块/段落/六级标题/打印/缩放),全局键盘处理先归一化组合键再查生效绑定分发,原有语义保持不变(IME 守卫、输入框内不触发内容类快捷键、保存走保存/另存为两条独立绑定)。 - 设置中心支持改绑(点击「修改」后按任意组合键录入,Esc 取消)、解绑、恢复单个默认;改绑命中他人组合键时弹出冲突提示,可选择「覆盖并解绑对方」;编辑器内置键(Ctrl+B/I、Tab 导航等)单列只读展示并注明不可改绑。覆盖随 UI 偏好持久化(SQLite/localStorage),即时生效。菜单上的快捷键标注仍为默认组合,改绑后以设置中心为准。
多窗口打开文档
- 文件菜单「在新窗口打开当前文档」:Tauri
WebviewWindow以doc-*标签创建新窗口,URL 带?file=<路径>参数;应用启动初始化时读取该参数自动打开对应文档。新窗口与主窗口共用 SQLite(最近文件/偏好/恢复记录一致),同文档双开编辑时由阶段 4 的外部修改基线检测兜底冲突提醒。 - 能力配置:
default.json的 windows 扩展为["main", "doc-*"],新增core:webview:allow-create-webview-window权限;新窗口同样使用无边框装饰设置。
2. 性能实测(沙箱口径)
tests/perf.test.ts(PERF_BENCH=1 时运行,默认跳过)用结构化文档(标题/段落/列表/表格/代码块混合)实测「建模 + 序列化」:
| 目标大小 | 实际字符 | 建模(create) | 全量序列化 |
|---|---|---|---|
| 100 KB | 61,342 | 2.2 s | 0.46 s |
| 1 MB | 625,870 | 29.8 s | 2.6 s |
口径说明(重要):这是 jsdom + 沙箱共享 CPU(1.5 核) 的数字——jsdom 的 DOM 操作比真实浏览器慢一个量级,属悲观上限,不是 WebView2 真机表现;可得的结论是成本随体积近似线性、序列化远快于建模。输入延迟在 jsdom 里无法测(无真实渲染管线),大文档真机手感列入 Windows 验收清单:重点验 100KB 文档输入跟手度与 1MB 文档打开等待;若真机 1MB 建模仍明显卡顿,阶段 7 前可再做「打开时占位 + 分片解析」优化,本阶段未预先做该改造(避免无真机数据拍脑袋)。
3. 验证
- 前端:
npx tsc -b0 错误;vitest 61 通过 + 2 跳过(跳过为性能基准门控),新增阶段 6 共 8 例:- 查找索引:跨文本节点命中映射、跨块命中跳过、大小写/整词/正则与非法正则报错;真实编辑器里查到 2 处、选中文本核对、替换后序列化文本正确;
- 快捷键注册表:默认绑定无冲突、覆盖/解绑/覆盖优先、冲突占用查询、事件归一化与展示格式;
- 专注模式:真实编辑器开启后非当前块 2 个段落带
focus-dim、关闭后消失; - 其余 53 例(阶段 1–5)无回归。
- Rust:
search.rs独立 crate 断言全过(上文);commands.rs通过 rustfmt 语法解析;workspace_search 命令与 lib 注册完成。Tauri 完整构建仍受沙箱系统库限制,Rust 命令签名类型待 Windows 构建确认。 - 生产构建通过;dev 冒烟 HTTP 200。
4. 已知边界(如实登记)
- 查找不做「全部命中高亮」,只有当前命中以选区形式高亮;源码模式替换走 CodeMirror changes(单次 dispatch,可撤销)。
- 全词匹配只对 ASCII 词边界有效(中文无词边界概念,与主流编辑器行为一致)。
- 全文搜索为同步命令:超大工作区(数千文件)可能有短暂等待,已有上限保护;结果点击定位到「该文件的第一个命中」而非具体行(打开后查找条定位首个命中,随后可逐个跳转)。
- 多窗口共用恢复记录:两个窗口同时退出时未保存草稿的恢复条目可能重复提示,以先处理为准(记录处理后即删除)。
- 菜单快捷键标注为默认组合键,改绑后不动态更新菜单文案(设置中心显示生效值)。
5. 下一阶段(阶段 7:测试与发布准备)
Win10/11 真机测试与验收清单总销账(阶段 0–6 累积清单)、安装包(nsis/msi)与便携版构建验证、自动更新通道设计与接入、版本号与发布说明、最终全量回归。