对齐 Wolai 侧栏体验并收拢设计入库
This commit is contained in:
@@ -0,0 +1,459 @@
|
||||
# [recycle] 文档访问性能根治重构路线 v1
|
||||
|
||||
> 更新时间:2026-04-16
|
||||
>
|
||||
> 相关文档:
|
||||
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
|
||||
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/process/ai-frontend-simplification-plan-v1.md`
|
||||
> - `/mnt/Data1T/mnote/design/old/08-legacy-rust-kernel/done/rust-kernel-cutover-v1.md`
|
||||
|
||||
## 1. 目标
|
||||
|
||||
这份文档只回答一个长期问题:
|
||||
|
||||
> **如果不满足于“临时优化”,而要从架构上根治文档访问和页面切换卡顿,mnote 应该重构成什么样。**
|
||||
|
||||
本文的目标不是“再做几处按需加载”,而是定义:
|
||||
|
||||
- 哪些前端能力应继续保留
|
||||
- 哪些能力应退出当前重前端壳
|
||||
- Rust Web 层应该采用什么形态
|
||||
- `BlockNote` 应该如何被隔离,而不是继续拖慢整个页面系统
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前事实
|
||||
|
||||
结合当前仓库结构,可以先确认四个事实:
|
||||
|
||||
### 2.1 当前最重的前端成本,不在服务端语言
|
||||
|
||||
当前文档页主链仍然是:
|
||||
|
||||
`documents/[id]/page.tsx -> DocumentShell -> DocumentContent -> BlockNoteEditor`
|
||||
|
||||
而且存在以下典型问题:
|
||||
|
||||
- 文档进入页面后仍有 `meta -> content -> editor` 的串行加载链
|
||||
- `DocumentShell` 与 `DocumentContent` 仍在客户端串联挂载
|
||||
- `BlockNoteEditor` 本身是当前最重的前端运行时之一
|
||||
- 文档页周边仍挂载多类抽屉、面板和桥接组件
|
||||
|
||||
这说明当前访问速度问题的核心,不是“Node 不够快”,而是:
|
||||
|
||||
> **页面切换时仍然把太多东西当成同一层前端运行时来初始化。**
|
||||
|
||||
### 2.2 当前只有一类能力明确难以短期替换
|
||||
|
||||
从产品结构看,短期最难替换的是:
|
||||
|
||||
- `BlockNote`
|
||||
|
||||
因为它同时承担:
|
||||
|
||||
- 文档编辑核心
|
||||
- 自定义 block 运行时
|
||||
- 当前正文交互和保存链
|
||||
|
||||
而下面这些东西,从长期看都不是必须继续绑在当前 React/Next 大壳里的:
|
||||
|
||||
- Sidebar / 页面树 / 文件树
|
||||
- 搜索壳与搜索结果面板
|
||||
- Mindmap
|
||||
- AI 面板
|
||||
- 历史 / 评论 / 回链 / 页面选项等周边面板
|
||||
- 在线表格
|
||||
|
||||
### 2.3 OnlyOffice 不应被当成主阻塞项
|
||||
|
||||
根据当前架构,OnlyOffice 本来就是独立页面型编辑器,不是正文内嵌主编辑器。
|
||||
|
||||
这意味着:
|
||||
|
||||
- 它不会决定文档页的首屏切换模式
|
||||
- 它可以继续保留“外挂页面/外部编辑器”定位
|
||||
- 它不应影响主文档访问性能路线判断
|
||||
|
||||
### 2.4 Mindmap 是优先级更高的可替换对象
|
||||
|
||||
当前 Mindmap 虽然复用了前端组件链,但它并不像 BlockNote 那样不可轻易动。
|
||||
|
||||
因此长期上:
|
||||
|
||||
- Mindmap 可以先于 BlockNote 重写
|
||||
- 它很适合作为“从当前重前端壳中剥离”的第一批对象
|
||||
|
||||
---
|
||||
|
||||
## 3. 根治原则
|
||||
|
||||
如果目标是“根治”,而不是“补丁式提速”,那么应遵守以下原则。
|
||||
|
||||
### 3.1 页面切换必须先回到“读优先”
|
||||
|
||||
当前问题的根子之一,是页面切换几乎默认在进入“编辑器世界”。
|
||||
|
||||
长期正确方向应改为:
|
||||
|
||||
- 先快速进入页面阅读态
|
||||
- 再按需进入编辑态
|
||||
- `BlockNote` 不得阻塞普通页面访问
|
||||
|
||||
换句话说:
|
||||
|
||||
> **文档页要从“先挂编辑器,再展示页面”改成“先展示页面,再按需挂编辑器”。**
|
||||
|
||||
### 3.2 除 `BlockNote` 外,其余能力应尽量退出当前重前端壳
|
||||
|
||||
长期目标不应是“继续给当前 Next/React 应用做瘦身”,而应是:
|
||||
|
||||
- 让能退出的都退出
|
||||
- 让必须保留在浏览器的只剩真正需要浏览器的那部分
|
||||
|
||||
理想形态是:
|
||||
|
||||
- 文档阅读页:极薄
|
||||
- 文档编辑岛:`BlockNote`
|
||||
- 外挂编辑器:OnlyOffice
|
||||
- 独立能力:Mindmap、AI、搜索、Sidebar 等各自最小化
|
||||
|
||||
### 3.3 Rust 化的意义在于“统一业务执行面”,不是“自动更快”
|
||||
|
||||
把东西改成 Rust 并不会自动让页面切换更快。
|
||||
|
||||
Rust 真正的价值在于:
|
||||
|
||||
- 统一业务执行平面
|
||||
- 让文档、块、导图、搜索、树结构、审计、AI 业务桥收口到同一体系
|
||||
- 支持更薄的前端和更强的 SSR / server-first 输出
|
||||
|
||||
所以“Rust 化”必须和“页面运行模型重构”一起发生,才构成根治。
|
||||
|
||||
---
|
||||
|
||||
## 4. 技术选型判断
|
||||
|
||||
这一节只回答一个问题:
|
||||
|
||||
> **长期重构时,到底是“就用 Rust”,还是要明确选择 `axum` 等 Rust Web 框架。**
|
||||
|
||||
结论先给出:
|
||||
|
||||
> **不能只说“用 Rust”。长期要落地,必须明确分层选型。推荐方案是:`axum` 作为 Web/服务承载层,配合 `Leptos Islands` 作为 server-first 页面壳;不推荐只用 `axum`,也不建议把 Dioxus/Yew 作为主文档访问层的第一选择。**
|
||||
|
||||
### 4.1 为什么不能只说“Rust”
|
||||
|
||||
“Rust”是语言,不是 Web 渲染方案。
|
||||
|
||||
如果只决定“以后改成 Rust”,但不明确:
|
||||
|
||||
- 服务端路由由谁承接
|
||||
- 页面 SSR 由谁承接
|
||||
- islands / hydration 模型由谁承接
|
||||
- 浏览器交互层由谁承接
|
||||
|
||||
那最后很容易回到:
|
||||
|
||||
- 只是把 API 改写成 Rust
|
||||
- 但前端页面模型仍然没变
|
||||
|
||||
这不能根治。
|
||||
|
||||
### 4.2 `axum` 的定位:非常适合做 Web 承载层,但不负责前端 UI 模型
|
||||
|
||||
官方 `axum` 文档显示,它非常适合承担:
|
||||
|
||||
- Router
|
||||
- Handler
|
||||
- Middleware
|
||||
- JSON / Query / Form / WebSocket / SSE
|
||||
- `tokio` 上的高并发服务
|
||||
|
||||
这使它非常适合作为 mnote 长期的:
|
||||
|
||||
- API 层
|
||||
- 文档查询层
|
||||
- 树结构聚合层
|
||||
- 搜索层
|
||||
- AI / Hermes 业务桥
|
||||
- SSR 页面外壳承载层
|
||||
|
||||
但要注意:
|
||||
|
||||
> **`axum` 不是前端渲染框架。它能承接 Web 服务,不会替你解决“页面如何减少 hydration、如何隔离 BlockNote”这类前端模型问题。**
|
||||
|
||||
因此,**只用 `axum` 不够。**
|
||||
|
||||
### 4.3 为什么推荐 `Leptos Islands`
|
||||
|
||||
官方 Leptos Islands 文档最值得关注的点是:
|
||||
|
||||
- 默认服务端组件不进入客户端
|
||||
- 只有显式 `#[island]` 的部分才被编译到浏览器
|
||||
- islands 应尽量“小而具体”
|
||||
|
||||
这和 mnote 的长期目标高度一致,因为你现在最想要的是:
|
||||
|
||||
- 绝大多数页面内容不再变成大块客户端运行时
|
||||
- 只有真正需要交互的部分进入浏览器
|
||||
- `BlockNote` 成为最后一个重交互 island
|
||||
|
||||
也就是说,Leptos Islands 的思路天然支持:
|
||||
|
||||
- 页面树/文件树作为轻交互 island
|
||||
- 搜索框作为轻交互 island
|
||||
- AI 面板作为独立 island
|
||||
- `BlockNote` 作为最后的重 island
|
||||
- 其余大量阅读内容只做 server-rendered HTML
|
||||
|
||||
这比“继续在全页 React hydration 里做局部优化”更接近根治。
|
||||
|
||||
### 4.4 为什么不把 Dioxus 作为主推荐
|
||||
|
||||
官方 Dioxus Fullstack 文档自己就把它定位得更偏“app-like”:
|
||||
|
||||
- 它支持 SSR
|
||||
- 但更强调交互型应用
|
||||
- 文档中明确区分 CSR 的 app 架构与 SSR 的 site 架构
|
||||
|
||||
而 mnote 的长期目标不是继续维持一个“整页 app 先跑起来”的文档访问模型,而是:
|
||||
|
||||
- 页面先出来
|
||||
- 交互再局部接上
|
||||
|
||||
所以 Dioxus 不是不能用,而是**不如 Leptos Islands 对这个目标直接。**
|
||||
|
||||
### 4.5 为什么不把 Yew 作为主推荐
|
||||
|
||||
Yew 更接近经典 Rust/WASM 前端框架。
|
||||
|
||||
它的问题不是能力不够,而是:
|
||||
|
||||
- 更偏客户端应用思路
|
||||
- 不天然突出 islands-first
|
||||
- 对你当前“尽量减少客户端代码、把交互压缩为少数岛”的目标,不是最优选
|
||||
|
||||
---
|
||||
|
||||
## 5. 推荐的长期方案
|
||||
|
||||
## 5.1 总体选型
|
||||
|
||||
推荐长期架构采用:
|
||||
|
||||
- **服务承载层:`axum`**
|
||||
- **页面壳与 islands 模型:`Leptos Islands`**
|
||||
- **业务执行面:现有 mnote Rust `core-protocol + bridge-runtime + storage-convex-bridge` 继续演进**
|
||||
- **AI runtime:Hermes API Server**
|
||||
- **最后保留的重编辑岛:`BlockNote`**
|
||||
|
||||
一句话版:
|
||||
|
||||
> **`axum` 负责服务,`Leptos` 负责薄页面与 islands,Rust 内核负责业务,Hermes 负责 agent,`BlockNote` 留作最后的重前端孤岛。**
|
||||
|
||||
## 5.2 为什么这是最适合 mnote 的方案
|
||||
|
||||
因为这个方案同时满足四个条件:
|
||||
|
||||
### A. 适合逐步迁移
|
||||
|
||||
你不需要一次性推翻所有前端。
|
||||
|
||||
可以先把:
|
||||
|
||||
- Sidebar
|
||||
- 页面树 / 文件树
|
||||
- 搜索壳
|
||||
- 阅读页
|
||||
- Mindmap
|
||||
|
||||
逐步迁到 `axum + Leptos`
|
||||
|
||||
再把 `BlockNote` 留在最后处理。
|
||||
|
||||
### B. 适合“读写分离”
|
||||
|
||||
`Leptos Islands` 很适合把页面拆成:
|
||||
|
||||
- 读页面:服务端输出
|
||||
- 写页面:局部 island
|
||||
|
||||
这正是文档访问性能根治的核心。
|
||||
|
||||
### C. 适合 Rust 单栈长期收口
|
||||
|
||||
当前你已经做过大范围 Rust 重构,未来继续统一到:
|
||||
|
||||
- Web 壳
|
||||
- 业务协议
|
||||
- AI 业务桥
|
||||
- CLI
|
||||
|
||||
会比继续维护“Rust 内核 + 重 Next 前端壳”的分裂状态更稳定。
|
||||
|
||||
### D. 风险可控
|
||||
|
||||
你不需要一开始就重写 `BlockNote`。
|
||||
|
||||
最难的部分可以留到最后,不会卡死整个长期路线。
|
||||
|
||||
---
|
||||
|
||||
## 6. 最终目标架构
|
||||
|
||||
长期目标建议收敛成下面这张逻辑图:
|
||||
|
||||
```text
|
||||
浏览器
|
||||
-> axum 路由层
|
||||
-> Leptos server-rendered 文档壳
|
||||
-> 少量 islands
|
||||
- Sidebar / 页面树 / 文件树
|
||||
- Search
|
||||
- AI 面板
|
||||
- Mindmap(重写后)
|
||||
- BlockNote(最后保留的重岛)
|
||||
|
||||
axum / Leptos
|
||||
-> mnote Rust 业务执行面
|
||||
- 文档
|
||||
- 块
|
||||
- 搜索
|
||||
- 导图
|
||||
- 审计 / trace / event
|
||||
|
||||
Hermes API Server
|
||||
-> 调用 mnote Rust 暴露的业务能力桥
|
||||
|
||||
OnlyOffice
|
||||
-> 继续独立页面 / 外挂编辑器
|
||||
```
|
||||
|
||||
在这个目标架构里:
|
||||
|
||||
- 页面切换不再默认进入“整页前端应用”
|
||||
- 绝大多数阅读内容不需要大块 hydration
|
||||
- `BlockNote` 成为唯一需要谨慎处理的大前端负担
|
||||
|
||||
---
|
||||
|
||||
## 7. 推荐迁移顺序
|
||||
|
||||
长期路线建议分四阶段,不建议一口气重做。
|
||||
|
||||
## Phase 1:先把文档访问模型改成 server-first
|
||||
|
||||
先做:
|
||||
|
||||
- 用 Rust Web 壳承接文档阅读态
|
||||
- 页面进入时直接输出 `meta + content`
|
||||
- 不再进入页面后再串行拉正文
|
||||
- 把“页面切换”和“编辑器启动”拆开
|
||||
|
||||
这一阶段的目标不是替换 BlockNote,而是先把它从切页主链里移走。
|
||||
|
||||
## Phase 2:优先重写可替换的常驻模块
|
||||
|
||||
优先级建议:
|
||||
|
||||
1. Sidebar / 页面树 / 文件树
|
||||
2. 搜索壳与搜索结果页
|
||||
3. 页面选项、历史、评论、回链等周边面板
|
||||
4. AI 面板
|
||||
|
||||
原因:
|
||||
|
||||
- 这些东西是跨页面常驻能力
|
||||
- 高频出现
|
||||
- 比 BlockNote 更容易先抽离
|
||||
|
||||
## Phase 3:重写 Mindmap,继续缩小前端重负担
|
||||
|
||||
Mindmap 是非常适合优先退出当前重前端壳的对象。
|
||||
|
||||
建议:
|
||||
|
||||
- 把导图数据和执行面继续放在 Rust
|
||||
- 前端重新实现为更轻的独立渲染层
|
||||
- 不再依赖当前文档页大壳去承载
|
||||
|
||||
## Phase 4:最后再处理 BlockNote
|
||||
|
||||
这时再决定:
|
||||
|
||||
- 是否继续保留 BlockNote,但隔离为独立 island
|
||||
- 是否逐步替换 BlockNote 的部分能力
|
||||
- 是否长期把编辑体验拆成更多 Rust 原生能力 + 少量 JS 编辑器兼容层
|
||||
|
||||
**在此之前,不建议把 BlockNote 当成第一刀。**
|
||||
|
||||
---
|
||||
|
||||
## 8. 非目标
|
||||
|
||||
为了避免路线漂移,下面这些都不应被误认为“根治方案”。
|
||||
|
||||
### 8.1 不是“把 Next API 改成 Rust 就算完成”
|
||||
|
||||
如果页面仍然是:
|
||||
|
||||
- 重客户端壳
|
||||
- 重 hydration
|
||||
- 切页即初始化编辑器
|
||||
|
||||
那只是服务端换语言,不是根治。
|
||||
|
||||
### 8.2 不是“先全面重写 BlockNote”
|
||||
|
||||
BlockNote 是最难对象,不应先作为第一刀。
|
||||
|
||||
正确顺序应是:
|
||||
|
||||
- 先移除外围负担
|
||||
- 最后再碰 BlockNote
|
||||
|
||||
### 8.3 不是“继续在当前 React 壳里无限做局部修补”
|
||||
|
||||
按需加载、拆组件这些短期仍有价值,但如果最终仍然保留:
|
||||
|
||||
- 大型客户端文档壳
|
||||
- 大型常驻 Sidebar
|
||||
- 大型客户端页面切换模型
|
||||
|
||||
那还是治标不治本。
|
||||
|
||||
---
|
||||
|
||||
## 9. 最终建议
|
||||
|
||||
如果以“根治文档访问性能”为唯一目标,我给出的长期技术判断是:
|
||||
|
||||
> **应该继续推进 Rust 主导重构,但不是笼统地说“以后用 Rust”,而是明确采用 `axum + Leptos Islands + mnote Rust 内核 + Hermes` 的组合。**
|
||||
|
||||
其中:
|
||||
|
||||
- `axum`
|
||||
适合做 Web 服务承载层、API、SSE、AI 业务桥、SSR 外壳。
|
||||
- `Leptos Islands`
|
||||
适合做 server-first 文档页和极小交互岛,是把 `BlockNote` 隔离成“最后一个重前端岛”的最佳路线。
|
||||
- `Dioxus`
|
||||
可以关注,但更适合作为偏 app 化交互场景的备选,不是当前文档访问性能根治的第一推荐。
|
||||
- `Yew`
|
||||
不作为当前主路线推荐。
|
||||
|
||||
最后用一句话收口:
|
||||
|
||||
> **mnote 的根治路线,不是“把现有前端改快一点”,而是“把除了 BlockNote 之外的大多数页面能力从当前重前端壳中迁出,交给 Rust 主导的 server-first Web 架构承载”。**
|
||||
|
||||
---
|
||||
|
||||
## 10. 外部参考
|
||||
|
||||
以下外部资料支持上面的技术判断:
|
||||
|
||||
- `axum` 官方文档:
|
||||
https://docs.rs/axum/latest/axum/
|
||||
- Leptos Islands 指南:
|
||||
https://book.leptos.dev/islands.html
|
||||
- Dioxus Fullstack SSR 文档:
|
||||
https://dioxuslabs.com/learn/0.7/essentials/fullstack/ssr/
|
||||
Reference in New Issue
Block a user