news 2026/9/7 6:01:30

LobeHub UX Audit 实战:以 Pages 模块审计为例,拆解「三层验证 + 模式回灌」的界面体验审查方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LobeHub UX Audit 实战:以 Pages 模块审计为例,拆解「三层验证 + 模式回灌」的界面体验审查方法

LobeHub UX Audit 实战:以 Pages 模块审计为例,拆解「三层验证 + 模式回灌」的界面体验审查方法

【免费下载链接】lobehub🤯 LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub

LobeHub 仓库内置了一个可复用的 UX 审计技能(ux-audit),其基准是 Jennifer Tidwell《Designing Interfaces》的模式语言加上项目自有的ux执行检查清单。本文以该技能自带的真实工作样本——Pages 模块(/page文档列表 +/page/[id]全屏富文本编辑器)的 L1 静态审计为例,完整拆解一次审计如何从「模式识别 → 亮点固化 → 缺陷排序 → 规则回灌」闭环推进,读者读完后可以掌握一套可重复执行、证据可溯源的单页面 UX 审查方法论。

一、ux-audit 技能:一次只审一个表面,三层各自能"看见"什么

page.md是 ux-audit 技能 的references/example/目录下的一组工作样本之一(同目录还有channel.mdhome.mdtask-detail.md等 20 余篇)。技能定义的核心原则有两条:

  1. 一次只审一个表面(surface)——整站扫描对单次运行负担太重;每个页面在产品演进中反复重审,这才是"持续"的含义。
  2. 结论必须来自能看见该问题的层。审计分三层,每层有独立的操作文件:
操作文件做什么能抓到什么成本
L1 静态layer-1-static.md读代码缺失的状态/分支(空态/错误/重试)、无草稿持久化、模式缺席、结构性问题便宜、离线,每次审计必跑
L2 视觉layer-2-visual.md对渲染后的表面截图真实视觉层级与主控件、间距/对比/对齐、截断溢出、空态/加载/错误态的真实观感、响应式断点、暗色模式中等,需要渲染环境
L3 动态layer-3-dynamic.md通过 acceptance 框架驱动真实用户旅程 + 埋点进行中/锁定态、强制触发的错误/空态、步骤衔接、焦点/键盘可达性、量化的 CLS/LCP/INP/长任务高,需要运行环境 + 认证

技能的"覆盖矩阵"规定:例如"空态是否是一个真正的页面"是 L2 结论,不能由 L1 对着variant属性打勾;"两个 A/B 变体谁更好"更是 L3/分析层结论,L1/L2 只能比较机制差异,无权宣布胜者。

page.md的头部就如实标注了自己的审计状态,这是全文最值得学习的方法论姿态:

已运行层:L1(静态/代码)✅——以下全部。L2(视觉)/ L3(动态 + CLS)⏳ 尚未运行——见 §5。本文所有关于渲染的结论都是 L1 推断,等待 L2 确认。

同时它也声明了自己是模板而非现状真理("Use it as a template for the output shape, not as current-state truth (the code moves; re-verify before citing)")——代码在动,引用前必须重新验证。本文在复述各结论时,已按当前仓库代码重新核对了关键证据位置。

审计对象是文档编辑器类表面,对标 Notion / Google Docs / Craft。技能要求先给表面命名"类别(class)",写出该类别的领域惯例清单,再对照找差距——因为只读自家代码只能暴露"已经建出来的东西"的缺陷,对"根本没建的能力"在结构上是盲的。

被审计表面的核心文件(load-bearing files):

  • 路由:src/routes/(main)/page/{index,_layout,[id]}(入口 index.tsx/page/index.tsx) 用Suspense+SurfaceSkeleton包裹PageExplorerPlaceholder
  • 侧边栏列表:src/features/Pages/PageLayout/*
  • 空态占位:PageExplorerPlaceholder
  • 编辑器 + Copilot + History + 编辑锁:src/features/PageEditor/*
  • 状态:src/store/page/*src/store/document/slices/editor/*
  • 分享视图:/share/page/[id](OSS 仓库中其错误/空态外壳是云构建的业务桩,见下文盲区说明)

二、§1 — 模式识别:这个表面用了哪些模式、用得好不好

L1 审计的第一步是把表面用到的界面模式对照 pattern-catalog.md 逐条列表评级。page.md的模式表完整如下(表格中的文件位置已按当前仓库结构给出):

模式(族)所在位置评级备注
Overview + Detail(导航/数据)侧边栏列表 →/page/[id]编辑器保持上下文位置
Deep-linking(导航)/page/:id/share/page/:idURL 可还原文档
Empty-state as onboarding(增长)主舞台PageExplorerPlaceholder(新建/上传/Notion 卡片)富 CTA——亮点
空态——侧边栏(数据)PageEmpty.tsx⚠️Empty无 CTA(差距 ⑦)
Loading Skeleton(反馈)Body+ListSkeletonList⚠️存在但无法进入失败态(差距 ①)
Failure + Retry(反馈)列表 / 历史 / 保存— 缺席该模块最大的系统性缺口(①②③④)
Autosave / Smart Defaults(输入)performSave/performMetaSaveAutoSaveHint⚠️saving→saved,无 failed(差距 ②③)
Draft safety(编辑)usePageDraft.ts(sessionStorage)⚠️只在锁降级时做快照(差距 ②)
Entity lifecycle(操作)删除/重命名/复制/导出/历史恢复✅⚠️Header 操作扎实;侧边栏操作静默(差距 ⑤)
Command History(操作)History/*——列表 + Compare + Restore有确认 + 进行中 + 错误 toast
Cancelability / lock(反馈)EditingIndicator/LockedAlert/LockStatusBanner三向、成熟——亮点
Lists at scale(数据)AllPagesDrawerVList)+loadMoreDocuments⚠️搜索只过滤已加载子集(差距 ⑥)
Modal Panel(导航)Copilot / History 右侧面板(RightPanelCopilot 复用共享 Conversation

一句话读法(原文结论):编辑器的实体生命周期协同锁是成熟的;弱点高度聚集在Feedback(失败态缺席、保存被吞成idleRead(加载失败伪装成空态;对部分列表做搜索)——与历次审计命中的软肋相同。

三、§2 — 亮点/优秀案例:重构时不许回退的清单

技能明确规定:只列缺陷的审计已经退化成 bug report。亮点是"回灌"循环的 ✅ 半区,是下一次重构的"不许回退"清单。Pages 审计认定了四个亮点:

  1. ✅ 亮点 — 三向协同编辑锁。EditingIndicator/LockedAlert/LockStatusBanner构成一个成熟、可读的 presence/lock 模型:把"别人正在编辑"在三个高度上可视化,而不是一个不透明的标志位;这是模块里唯一把可取消性/并发端到端暴露出来的地方,重构必须保持三者同步。
  2. ✅ 亮点 — Command History 端到端暴露失败。History/*(History/index.tsx)的列表 + Compare + Restore 带确认 + 进行中 + 错误 toast;是模块里唯一把失败态一路带到用户面前的流程(与差距 ②③④ 中被吞掉的保存/元数据/历史失败形成 ✅ 对照),这正是它"承重"的原因。
  3. ✅ 亮点 — Header 实体生命周期做对了(→ 已落地为 ux Act §3.1 的 ✅ 案例)。编辑器 Header 的删除/重命名/复制/导出/恢复中,复制操作做了 try/catch + 成功/错误message(Header/useMenu.tsx)——与差距 ⑤ 里静默的侧边栏操作形成对照:同样的意图,这里变更能暴露自己的失败。
  4. ✅ 亮点 — 主舞台空态即引导。PageExplorerPlaceholder(PageExplorerPlaceholder.tsx)的新建/上传/Notion 卡片把"无文档"状态变成了富 CTA,而不是死空间——增长侧"空态是起点"模式的规范实现(差距 ⑦ 的侧边栏空态是它的 ⚠️ 反例)。

四、§3 — 体验差距(按严重度排序)

技能的严重度标尺:🔴破坏信任(数据/输入丢失、永久卡死、误导性"空态"掩盖失败、静默发送失败);🟠死路或误导(无前进路径、状态含糊、缺进行中反馈);🟡摩擦/不一致/错失惊喜。以下 8 项差距 + 1 个盲区全部继承原文档,并对关键证据在当前仓库中重新定位。

① 侧边栏列表拉取失败 → 永久骨架屏 — Feedback §4.2 🔴

useFetchDocuments只在成功回调onData中写入documents(action.ts 中onData: (documents) => { ... internal_dispatchDocuments({ documents, type: 'setDocuments' }) }),而isDocumentsLoading = documents === undefined(selectors.ts 第 9 行)。Body在 loading 期间渲染SkeletonList拉取出错时documents保持undefined→ 骨架屏永远转,没有错误、没有重试——这是典型的"初始化标志被成功回调门控"陷阱。

② 正文自动保存静默失败 + 草稿缺口 — Feedback §4.4 / Edit §2.1 🔴

performSave的 catch 分支中,非锁错误只把状态复位为saveStatus: 'idle'(action.ts 的catch块:仅CONFLICTsaveBlockedByLockFORBIDDEN弹 toast,其余只console.error后回到idle)。状态枚举是idle | saving | saved根本没有failed(initialState.ts 第 65 行)。只有CONFLICT(锁)会被表面化;网络错误/500 在用户看来与成功无法区分。同时isDirty保持 true,但 usePageDraft 只在锁不健康时才做快照——健康锁下的持续性保存失败既没有 failed 态、也没有草稿备份,刷新即静默丢失工作成果。

③ 元数据(标题/emoji)保存失败静默 — Feedback §4.4 🟠

PageEditor/store/action.ts 中performMetaSave的 catch 同样把metaSaveStatus复位为'idle'——再次没有failed。一次没持久化成功的标题/emoji 编辑,界面上看不出任何异常。

④ 历史加载失败伪装成"没有历史" — Read §1.1 🟠

History 的 SWR 解构只取了{ data, isLoading },丢掉了error(History/index.tsx);渲染逻辑是items.length === 0 ? <Empty "no history"/>。拉取失败 → 直接落到空态、无重试 → 用户会读到"这篇文档没有版本"这样的错误事实。

⑤ 侧边栏新建/重命名/复制静默失败 — Act §3.1 🟠

createNewPage出错时 rethrow(crud/action.ts),但调用方(AddButtonPageExplorerPlaceholder的新建入口)是 fire-and-forget——无 catch、无 toast;乐观插入的页面闪现一下就消失,还附带一个 unhandled rejection。侧边栏重命名(Editing)与复制(Item/useDropdownMenu)只有console.error不一致之处:编辑器 Header 的复制做对了(try/catch + 成功/错误message,Header/useMenu.tsx)——同一意图,两套反馈行为。

⑥ "全部页面"搜索只过滤已加载子集 — Read §1.2 🟠

AllPagesDrawer 的Contenttitle/content.includesallFilteredDocuments做客户端过滤,且滚动加载在搜索中会中止。500 篇页面只加载了 40 篇时,搜索一个未加载的页面会返回"无结果"——但它是存在的:一个假空态(分页排序必须走服务端规则的读侧孪生问题)。

⑦ 侧边栏空态没有 CTA — Read §1.1 🟡

PageEmpty.tsx只渲染一段描述(它确实区分了"没有页面"与"搜索无匹配"——这点做得好),但缺少"创建你的第一页"动作;富 CTA 只存在于主舞台占位符中,侧边栏空态因此是一个安静的死胡同。

⑧ 硬编码英文字符串 — i18n 🟡

PageExplorerPlaceholder中直接渲染了字面量'Uploading...',而不是走t()国际化 key——多语言用户会看到英文残留。

⏳ 盲区:分享视图的错误/空态是云构建桩 — 无法在 OSS 仓库审计

分享视图把数据与错误交给业务外壳渲染,而 OSS 仓库里的 PublishedShell.tsx 忽略data/error直接返回{children},所以一个失败/不存在的分享链接会渲染空白。真实行为在业务包(cloud build)里——只能留待 L2/L3 在云构建上确认。原文档明确把这一点列为"盲点"而不是"缺陷",正是"证据边界"规则的体现:L1 在 OSS 仓库里看不见它的真实状态。

五、§4 — 技能反馈:审计如何回灌ux检查清单

page.md的第四节记录了一次审计如何反哺技能体系("回灌"循环)——这是整个方法论"持续"的关键:

  • 新增/强化落地的ux条目
    • Feedback§4.4— 新增检查清单行 + PageEditor ❌ 案例:保存状态枚举必须能够表示失败catch里复位到idle是把静默写入烧进类型的陷阱(差距 ②③)。
    • Act§3.1— 新增"乐观变更必须暴露失败"规则 + ❌(侧边栏新建/重命名/复制)vs ✅(Header 复制)对照案例(差距 ⑤)。
    • Read§1.2— 新增"对分页列表的搜索必须查询服务端全量"规则,AllPagesDrawer作为 ❌ 案例(差距 ⑥)。
    • 每条同步镜像进 SKILL.md 的 Quick review。
  • 验证了既有规则(提供了好的 ❌ 引用案例):§4.2 永久骨架屏(差距 ①)、Read §1.1 空态 vs 失败(差距 ④)、Read §1.1 空态需要 CTA(差距 ⑦)。

技能文档强调:ux是审计的度量基准,审计是让ux保持诚实的机制——每次运行结束前必须完成"落地"三步:修掉最严重的 🔴 或建单、把可泛化差距回灌成检查清单条目(含 ✅/❌ 案例 + Quick review 镜像行)、把审计本身存为references/example/<page>.md供下次复用。如果一次运行真的没有可泛化的差距,也要在报告里明确写出来——沉默不是合法的收尾。

六、§5 — 待办:L2 视觉 + L3 动态

page.md明确声明本次是 L1-only,并在文末列出了后续必须执行的确认项——这示范了"结论只声明自己证据层能支撑的部分":

L2(视觉)——确认:侧边栏空态(PageEmpty)的真实观感(死空间还是页面感);Copilot / History 右侧面板布局;编辑器单一主操作是否清晰;占位符卡片在窄屏与暗色模式下的表现。

L3(动态)——逐项强制故障来证实差距:

  • 列表拉取离线 →实时确认差距 ①(永久骨架屏、无重试);
  • 健康锁下强制保存 500 →确认差距 ②(静默"看起来成功"态、无草稿 → 刷新丢工作成果);
  • 强制历史拉取报错 →确认差距 ④(显示"没有历史");
  • 驱动新建/重命名/复制失败 →确认差距 ⑤(条目消失、无 toast);
  • 在全部页面抽屉中搜索一个未加载的页面 →确认差距 ⑥(假空态);
  • 测量骨架屏→内容切换与 Copilot 挂载过程中的编辑器 CLS/LCP

七、从这篇工作样本能学到什么

page.md的价值不在"Pages 模块有 8 个缺陷"这个结论本身,而在于它展示了可复制的审计形状:

  1. 先声明审计层与盲区(L1 已跑 / L2、L3 未跑 / 云构建桩不可见),每个结论都挂在它能被"看见"的层上;
  2. 模式表 + 亮点 + 差距三件套:亮点与差距对等成文,file:line级证据,亮点直接变成检查清单的 ✅ 案例与重构回退保护线;
  3. 差距按严重度排序并标注违反的具体清单条目(Feedback §4.2、Read §1.1 等),使每个发现可独立检索、可验证;
  4. 回灌闭环:可泛化的差距成为新的规则 + ❌ 案例,优秀实现反过来 sharpen 规则文本——审计跑完,检查清单比跑之前更锋利;
  5. 待办即承诺:L2/L3 的强制故障脚本写清楚,下一轮审计可以从这份清单直接续跑。

在 LobeHub 仓库中,这套样本与 ux-audit 技能定义、三层操作文件(L1 / L2 / L3)以及references/example/下的其他模块样本共同构成了一套"以证据而非感觉"的界面体验治理流程;而本文所引的全部代码证据(src/store/pagesrc/store/document/slices/editorsrc/features/PageEditorsrc/features/Pages/PageLayout)都可以按文中路径直接在当前仓库中复核——这正是该技能反复要求的:引用之前,重新验证。

【免费下载链接】lobehub🤯 LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 6:01:10

智驾跑山零接管背后:感知、规划与控制如何协同保障安全

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 6:00:49

Windows FanControl风扇控制完整教程:四步让电脑不再呼啸

Windows FanControl风扇控制完整教程&#xff1a;四步让电脑不再呼啸 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending…

作者头像 李华
网站建设 2026/9/7 5:59:43

DependenciesGui使用指南:解决Windows DLL缺失与依赖排查

简介&#xff1a;DependenciesGui-windows10-depends 是一款面向 Windows 10 用户的依赖分析工具&#xff0c;可用于查看 PE 文件对 DLL、驱动等组件的依赖关系&#xff0c;定位程序加载失败或缺少动态库的问题&#xff0c;也能帮助开发者优化打包部署流程。资源包共计 35 个文…

作者头像 李华
网站建设 2026/9/7 5:57:42

MMD动画制作全流程解析:从3D建模到镜头特效实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 5:56:56

短视频平台技术架构与开发实践全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华