乐观 UI,英文叫 Optimistic UI。
意思是:
前端先假设这次操作会成功,所以立刻更新界面;后端慢慢处理,成功了就保持,失败了再回滚或提示错误。
比如聊天发送消息。
普通写法是:
1 | await sendMessageToServer(content) |
效果是:
你点发送后,要等服务器确认成功,消息才出现在界面上。用户会感觉卡。
乐观 UI 写法是:
1 | messages.value.push(userMessage) |
效果是:
你一按发送,消息立刻出现在聊天框里。服务器还没确认,但前端先“乐观地相信它会成功”。
你的代码里这里就是乐观 UI:
1 | messages.value.push({ id: nextMessageId++, role: 'user', content }) |
它没有等 /chat/stream 返回,先把用户消息和 AI 空气泡塞进页面里。
所以你应该立刻看到:
1 | 你:你好 |
这个 | 是你模板里的:
1 | <span v-else class="typing-cursor">|</span> |
也就是 AI 正在生成的占位符。
乐观 UI 的好处是:快。用户感觉软件很灵敏。
坏处是:状态容易打架。比如你这个 Bug:
1 | 1. 前端乐观地 push 消息 |
所以乐观 UI 常常要配合几个东西:
1 | status: 'sending' | 'sent' | 'failed' |
比如:
1 | messages.value.push({ |
后端成功后:
1 | message.status = 'sent' |
失败后:
1 | message.status = 'failed' |
也就是微信/QQ 那种:
1 | 发送中... |
一句话总结:
乐观 UI 就是:前端先装作成功,把界面更新了;后端如果真的成功就皆大欢喜,失败了再补救。
打个比方:
你去食堂点饭,老板还没做完,小幽已经先帮你把餐盘放桌上了。饭来了就开吃;饭没了,就把餐盘撤掉并告诉你“今日售罄”。这就是乐观 UI。