docs: Phase 8 — 性能基线 + 完整功能清单
在 Windows 11 x64 / Rust 1.98.1 / Slint 1.18 上实测:Release EXE 10.31 MB / 测试 22 passed / 启动后 RSS 153 MB / 空闲 CPU 0.15%。RSS 高于 AGENTS.md §33 的 50 MB 目标,原因是 Slint 1.18 默认 femtovg 后端的 GUI 堆占用约 120–150 MB;业务层只占很小一部分。README 记录所有 Phase 1–7 状态 + 已知限制。
This commit is contained in:
@@ -6,9 +6,20 @@
|
|||||||
|
|
||||||
## 状态
|
## 状态
|
||||||
|
|
||||||
🚧 **从 0 起步** —— 当前仓库只有目录骨架与占位 `Cargo.toml`,尚未进入 Phase 1(Bootstrap)。
|
✅ **Phase 1–7 完成**(Bootstrap → Polish)。Phase 8 性能基线已记录。
|
||||||
完整 8 阶段路线图见 `AGENTS.md` §57。
|
完整 8 阶段路线图见 `AGENTS.md` §57。
|
||||||
|
|
||||||
|
| 阶段 | 内容 | Commit |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 Bootstrap | Cargo + Slint hello + windows_subsystem + logging + error | `b30b2f0` |
|
||||||
|
| 2 C1–C3 | MainWindow + Sidebar + Mock 消息 + Settings + Dialogs + 窗口状态 | `49cbd9e` `11a1222` `680fbfa` |
|
||||||
|
| 3 C1–C2 | Gotify REST 客户端 + 真实数据接入 + Connection status | `c6ad388` `0cf7a4e` |
|
||||||
|
| 4 C1–C2 | WebSocket + 退避 + WS worker + UI drain | `319eeb4` `0b766f4` |
|
||||||
|
| 5 C1–C2 | AppConfig 持久化 + Theme + last_message_id | `07317e2` `28524b4` |
|
||||||
|
| 6 C1–C3 | 单实例 + 开机自启动 + close-to-tray + 托盘 + URL 打开 | `ac5d0cb` `e1622b5` `1df0723` |
|
||||||
|
| 7 C1–C3 | 托盘菜单增强 + Win32 Toast + URL 接线 + Priority 过滤 + 详情面板 | `1d5e4e3` `3010526` `97becf5` |
|
||||||
|
| 8 | 性能基线(本文档) | TBD |
|
||||||
|
|
||||||
## 目标平台
|
## 目标平台
|
||||||
|
|
||||||
- Windows 10 x64
|
- Windows 10 x64
|
||||||
@@ -19,11 +30,11 @@
|
|||||||
|
|
||||||
| 层 | 选型 |
|
| 层 | 选型 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 语言 | Rust stable |
|
| 语言 | Rust stable (1.98.1 实测) |
|
||||||
| UI | Slint 1.17.x |
|
| UI | Slint 1.18 |
|
||||||
| HTTP | `reqwest`(blocking + rustls) |
|
| HTTP | `reqwest` 0.12(blocking + rustls) |
|
||||||
| WebSocket | `tungstenite` |
|
| WebSocket | `tungstenite` 0.21(rustls + handshake) |
|
||||||
| Windows 集成 | `windows-rs` focused crates(按需引入) |
|
| Windows 集成 | `windows-sys` 0.59 focused features |
|
||||||
| 配置 / 状态 | JSON 文件(`%APPDATA%/WindowsGotify/`) |
|
| 配置 / 状态 | JSON 文件(`%APPDATA%/WindowsGotify/`) |
|
||||||
| 日志 | `tracing` + `tracing-subscriber` |
|
| 日志 | `tracing` + `tracing-subscriber` |
|
||||||
|
|
||||||
@@ -34,30 +45,109 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
Windows-Gotify-Client-Rust/
|
Windows-Gotify-Client-Rust/
|
||||||
├── Cargo.toml # 占位 — 见 AGENTS.md §44
|
├── Cargo.toml
|
||||||
├── AGENTS.md # AI Agent 实施计划(1363 行)
|
├── Cargo.lock
|
||||||
|
├── AGENTS.md # AI Agent 实施计划
|
||||||
├── README.md
|
├── README.md
|
||||||
├── LICENSE # MIT(占位)
|
├── LICENSE # MIT
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
├── assets/ # 图标、字体等
|
├── assets/ # 图标占位
|
||||||
├── ui/ # Slint 视图
|
├── ui/ # 8 个 .slint 文件
|
||||||
├── src/ # Rust 业务代码
|
│ ├── app.slint # MainWindow + Sidebar
|
||||||
│ ├── gotify/ # HTTP + WebSocket
|
│ ├── message-list.slint # 列表 + priority 过滤
|
||||||
│ ├── storage/ # config.json / state.json
|
│ ├── message-card.slint # MessageItem + 单卡片
|
||||||
│ ├── windows/ # 托盘 / Toast / 启动 / 单实例 / URL
|
│ ├── settings-page.slint # 5 分组设置
|
||||||
│ └── services/ # 生命周期
|
│ ├── empty-state.slint
|
||||||
├── tests/ # 集成测试
|
│ ├── dialogs.slint # AboutDialog
|
||||||
└── scripts/ # PowerShell 构建脚本
|
│ ├── server-card.slint
|
||||||
|
│ ├── theme.slint
|
||||||
|
│ └── components.slint # NavItem / SectionLabel / Divider
|
||||||
|
├── src/
|
||||||
|
│ ├── main.rs # windows_subsystem + 单实例
|
||||||
|
│ ├── lib.rs # 全部 wiring
|
||||||
|
│ ├── config.rs # ActiveConfig (Clone)
|
||||||
|
│ ├── models.rs # MessageItem 适配 + mock + try_fetch_initial_data
|
||||||
|
│ ├── error.rs
|
||||||
|
│ ├── logging.rs
|
||||||
|
│ ├── gotify/ # api + websocket + reconnect + model
|
||||||
|
│ ├── storage/ # config.json + state.json
|
||||||
|
│ └── windows/ # single_instance + startup + tray + url
|
||||||
|
├── tests/ # 22 测试(22 passed)
|
||||||
|
└── scripts/ # 预留
|
||||||
```
|
```
|
||||||
|
|
||||||
## 开发环境
|
## 开发
|
||||||
|
|
||||||
> 本仓库目前还没有源码,本节将在 Phase 1 完成后补全具体的 `cargo run` / `cargo build --release` 步骤。
|
```powershell
|
||||||
|
# 编译(debug)
|
||||||
|
cargo build
|
||||||
|
|
||||||
|
# 编译(release,单 exe,无控制台窗口)
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
# 测试(22 个)
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# 运行(debug 含 console,release 无 console)
|
||||||
|
cargo run --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## 性能基线(Phase 8 实测)
|
||||||
|
|
||||||
|
在 Windows 11 x64 / Rust 1.98.1 / Slint 1.18 上:
|
||||||
|
|
||||||
|
| 项 | 实测值 | AGENTS.md 目标 |
|
||||||
|
|---|---|---|
|
||||||
|
| Release EXE 大小 | **10.31 MB** | 记录实际,不硬性规定 |
|
||||||
|
| Release 编译时间(clean) | ~56 s | — |
|
||||||
|
| Tests | 22 passed / 0 failed | — |
|
||||||
|
| 启动后空闲 RSS | **153 MB** | < 50 MB(未达,受 Slint/Winit GUI 堆影响) |
|
||||||
|
| 启动后空闲线程数 | 28 | — |
|
||||||
|
| 启动后空闲 Handle 数 | 529 | — |
|
||||||
|
| 空闲 CPU(持续 30s) | ~0.15% | 接近 0%(达成) |
|
||||||
|
| Debug EXE | 35.66 MB / 控制台 | — |
|
||||||
|
| 启动 ~5s 后 CPU 累积 | ~0.77 s | — |
|
||||||
|
|
||||||
|
**关于 RSS**:Slint 1.18 在 Windows 上使用 `femtovg` 路径(默认),自身初始化就占用 ~120–150 MB 堆。Winit 后端还会为 GPU surface 与窗口堆保留一块。本项目业务层(Gotify 客户端 + 托盘 + 状态机)的额外占用很少。要进一步压缩需要换 Slint 的 `software` 后端或自行精简 femtovg 资源;对一个常驻型客户端来说,150 MB 仍在 Windows 11 上合理范围内(Task Manager 里 150 MB 的常驻进程很常见)。
|
||||||
|
|
||||||
|
**关于 EXE 大小**:当前 `release` profile 用了 `opt-level = "z"` + `lto = true` + `codegen-units = 1` + `panic = "abort"` + `strip = true`。再进一步压可考虑 `wasm-opt` 类工具或拆分依赖,但 V1 不值得为几百 KB 引入复杂度。
|
||||||
|
|
||||||
|
## 功能清单(Phase 7 完成后)
|
||||||
|
|
||||||
|
- ✅ Gotify HTTP REST(`/health`, `/application`, `/message?limit=`)
|
||||||
|
- ✅ Gotify WebSocket 实时消息 + 1s/2s/4s/8s/16s/30s 指数退避
|
||||||
|
- ✅ 多 server 配置(V1 仍只连接一个 active server)
|
||||||
|
- ✅ `%APPDATA%/WindowsGotify/config.json` 持久化
|
||||||
|
- ✅ `%APPDATA%/WindowsGotify/state.json` 持久化(窗口尺寸、主题、上次 last_message_id)
|
||||||
|
- ✅ 启动时 `since=last_message_id` 增量 catch-up
|
||||||
|
- ✅ 系统托盘(Open / New messages: N / Pause notifications / Settings / Restart connection / Quit)
|
||||||
|
- ✅ 单实例(`Local\` Mutex)+ 第二次启动激活现有窗口(`RegisterWindowMessageW`)
|
||||||
|
- ✅ close-to-tray + HKCU Run 开机自启动
|
||||||
|
- ✅ 系统级 Toast 通知(Win32 `NIF_INFO` + `Shell_NotifyIconW`,Win10+ 走 Action Center)
|
||||||
|
- ✅ Toast 偏好:master switch / High / Max / 托盘菜单 pause
|
||||||
|
- ✅ 点击消息打开 `click_url`(严格 http/https scheme 校验)
|
||||||
|
- ✅ Priority 过滤(All / Low / Normal / High / Max,sidebar)
|
||||||
|
- ✅ 消息详情面板(右侧 360px,app + priority + title + timestamp + body + Open link 按钮)
|
||||||
|
- ✅ Dark / Light / System 主题(每次启动从 state.json 恢复)
|
||||||
|
- ✅ Settings:Appearance / Connection / Notifications / Startup / Appearance / Advanced 占位
|
||||||
|
- ✅ Settings 切换实时持久化 + 通知 Toast 偏好同步到 TrayState
|
||||||
|
- ✅ Bearer Token 日志脱敏(`HeaderValue::set_sensitive(true)`)
|
||||||
|
|
||||||
|
## 已知限制 / 未做
|
||||||
|
|
||||||
|
- ❌ Markdown 渲染(`client::display` text/markdown)—— V1 纯文本足够;后续可加纯 Rust parser
|
||||||
|
- ❌ 真正的图标资源(tray NULL + window 默认)—— 需要真 `.ico` 文件
|
||||||
|
- ❌ Restart connection 仅 refetch,不真正断开 WebSocket worker
|
||||||
|
- ❌ 多 server UI 切换(仅支持 active_server 单连接)
|
||||||
|
- ❌ 搜索框(仅 Priority 过滤,无文本搜索)
|
||||||
|
- ❌ Copy message body 按钮
|
||||||
|
- ❌ Windows Credential Manager 加密 Token
|
||||||
|
- ❌ 国际化(仅英文 UI)
|
||||||
|
|
||||||
## 隐私与安全
|
## 隐私与安全
|
||||||
|
|
||||||
- App Token 默认以 JSON 明文存储在 `%APPDATA%/WindowsGotify/config.json`,仅当前用户可访问
|
- App Token 默认以 JSON 明文存储在 `%APPDATA%/WindowsGotify/config.json`,仅当前用户可访问
|
||||||
- 日志永不打印完整 `Authorization` 头
|
- 日志永不打印完整 `Authorization` 头(`HeaderValue::set_sensitive(true)`)
|
||||||
- 通知点击的 `click.url` 仅允许 `http://` / `https://`,拒绝 `file://` / `javascript:` / 自定义 scheme
|
- 通知点击的 `click.url` 仅允许 `http://` / `https://`,拒绝 `file://` / `javascript:` / 自定义 scheme
|
||||||
- 详细策略见 `AGENTS.md` §13 / §20 / §38 / §51
|
- 详细策略见 `AGENTS.md` §13 / §20 / §38 / §51
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user