工笔层染给生成式UI的启发:内容未齐,交互先别着急

发布时间:2026/10/25 12:56:39
工笔层染给生成式UI的启发:内容未齐,交互先别着急

一张动态卡片可能先有标题,再有两项字段,最后才收到允许提交的业务状态。把每次更新都当成“卡片完成”,用户就会遇到按钮忽然可点、字段随后又变、焦点被挤走的问题。工笔画的层染可以用来理解这种展开:底稿先稳定,信息随后进入,最终的交互权限另有一道工序。

这是一种设计比喻,不是渲染性能结论。它对应的工程问题是:展示进度与允许操作的状态,能否分别表达?

四个状态,解决四种不同的等待

empty尚未开始;loading已请求但没有有效内容;partial有内容但业务对象不完整;ready才表示必要字段与约束已确认。失败与取消另外建模,不能挤进“加载中”。

外框稳定不等于把高度永远写死。短文本可以给合理最小高度,长内容仍应允许扩展。图里四张卡片保持相同外框,是为了对比状态,不是在建议所有产品强制等高。

10月更新的WebMCP说明将工具作为网页的渐进增强,并保留用户可见的页面流程。对生成式界面,我更关心这个含义:Agent能调用功能,并不意味着屏幕可以丢掉人与系统之间的状态解释。

先验证状态机,再接组件

下面的模型不依赖Vue或React。字段是否齐全由业务确认,字符流结束只表示传输结束;两者缺一都不能提交。示例不把模型说出的“完成”当授权。

import assert from 'node:assert/strict'; function reduce(state, event) { if (event.type === 'start') return { phase: 'loading', text: '', complete: false }; if (event.type === 'cancel') return { ...state, phase: 'cancelled' }; if (['cancelled', 'failed', 'ready'].includes(state.phase)) return state; if (event.type === 'error') return { ...state, phase: 'failed' }; if (event.type === 'delta') return { ...state, phase: 'partial', text: state.text + event.text }; if (event.type === 'end') return { ...state, complete: true, phase: 'partial' }; if (event.type === 'validated' && state.complete) return { ...state, phase: 'ready' }; return state; } let s = reduce({}, { type: 'start' }); s = reduce(s, { type: 'delta', text: '两件商品' }); s = reduce(s, { type: 'validated' }); assert.equal(s.phase, 'partial'); s = reduce(s, { type: 'end' }); s = reduce(s, { type: 'validated' }); assert.equal(s.phase, 'ready'); s = reduce(s, { type: 'cancel' }); assert.equal(reduce(s, { type: 'delta', text: '迟到内容' }).text, s.text); console.log('progressive UI state checks passed');

组件可以从phase派生按钮状态和辅助文案,而不是在多处各维护一个isLoading。取消后的迟到事件不会继续追加;开始新任务时则创建新状态,不能悄悄复用旧结果。

留白也包括给读者保留控制权

加载时保持按钮位置;部分内容到达后,让用户能够阅读和停止;完成前不要把未核验的金额或资格变成可提交事实。自动滚动只在用户仍处于末尾时跟随,用户向上阅读后应停下。屏幕阅读器的播报也应按段落节制更新,避免逐字抢占。

Chrome的流式渲染建议讨论了重新解析历史内容的成本及富文本清洗。这里的状态机与这些问题互补:解析器负责内容,状态机负责什么时候允许用户依赖它。

上面的JavaScript状态测试在Node v26.3.0通过;CSS布局、焦点、无障碍播报和真实Agent调用未做浏览器集成测试。示例也不承诺完整JSON Schema校验,需要业务另行接入。