跳到正文

乐观更新

Optimistic UI

点下去界面立刻变成成功的样子,请求在后台跑,失败了再退回去。

  • 又叫:
  • 乐观更新
  • 先改后存
  • 点了立刻变
  • optimistic update
  • rollback on failure
  • immediate UI
展厅
交互反馈
形态
固定舞台
播放
手动触发
关键词
需要 JS / 有状态 / 键盘可用 / 可以直接用
↕ 自己动手试试
F-05形态 固定舞台播放 手动触发Optimistic UI

参数工作台

复制给 AI

随参数实时更新

做一个乐观更新(optimistic UI)的点赞列表:点击后立刻把这一条改成已赞、计数 +1,同时标记 pending,不等接口返回。模拟请求延迟 1200ms,失败概率 30%,失败时按 id 回滚到原状态并在那一条上显示「失败,已撤销」的提示。用 useOptimistic 或本地 state 实现,注意快速连点的竞态。

什么时候用

  • 点赞、收藏、关注这类高频、低风险、可重复的操作
  • 发送消息或评论,希望它立刻出现在列表里,而不是等服务器回声
  • 网络慢的时候想减少等待感,把结果先摆出来

适用场景:列表 / 按钮 / 表单

推荐取值

界面更新延迟
0ms(点击即变)
失败提示停留
2–4s
请求超时
5–10s
回滚过渡
200–300ms

别搞混

  • 和「加载中(loading / disabled)」的区别

    loading 明确说「正在提交,先等一下」,还会把按钮锁住;乐观更新反过来,先显示结果、把等待藏起来,只在失败时才提示并回滚。

  • 和「本地缓存(local cache)」的区别

    乐观更新只改当前这一次的界面状态,刷新就没了;缓存是真正存下来的数据,下次打开还在。

容易踩的坑

  • 支付、下单、删除账号这类不能重放的操作不能乐观,必须等服务器确认
  • 失败必须回滚并给出提示(toast 或内联错误),只回滚不提示,用户会以为自己成功了
  • 快速连点会产生竞态,给请求编号或声明「最后一次为准」,别让旧响应覆盖新状态
  • 回滚要按 id 定位那一条,不要按数组下标,否则列表并发更新时会改错行

无障碍降级

回滚的颜色和位移过渡在 prefers-reduced-motion 下取消,状态直接切换,但「已撤销」的文字或图标提示必须保留。

关键词

  • optimistic UI
  • rollback
  • useOptimistic
  • race condition
  • pending state
  • reconcile

参考

相关展品