让你的应用瞬时响应,使用 Optimistic Updates

发布: (2026年2月4日 GMT+8 05:35)
9 min read
原文: Dev.to

I’m happy to translate the article for you, but I need the full text of the post. Could you please paste the content you’d like translated (excluding the source line you’ve already provided)? Once I have the article text, I’ll translate it into Simplified Chinese while preserving the original formatting, markdown, and code blocks.

那一瞬间的摩擦

你知道在点击 “赞” 时,心形图标填满前的那一点点等待吗?那一瞬间你不确定是否成功的感觉?这不仅让人烦恼——它在侵蚀用户与界面之间的信任。

我在构建 AI 聊天功能时深有体会。用户发送消息后,消息在聊天窗口出现前会有一段尴尬的停顿。虽然 API 大约在 200 ms 内返回,但感觉却很迟钝。人们会再次点击 发送,以为之前的点击没有生效。功能本身很快,却没有 感觉 快。

这时我发现了 乐观更新(optimistic updates),说实话,它彻底改变了我对构建界面的思考方式。

实际等待时发生了什么

大多数应用的流程是这样的:

  1. 用户执行某个操作。
  2. 显示加载指示。
  3. 等待服务器确认。
  4. 更新 UI。

这种方式安全且可预测,但也会让你的应用感觉像在泥浆中前行。

从用户的角度来看,他们只是让你的应用去做一件事。他们点击了按钮,做出了决定。为什么要等服务器的许可才能看到自己操作的结果?

关键是,大多数操作都会成功。约 99 % 的情况下 API 调用会返回成功,我们却让用户为那 1 % 的失败概率等待。

乐观的做法

思维转变: 假设操作会成功,立即更新 UI,只有在真的出错时再处理失败。

  • 当有人在聊天中发送消息时,立刻显示出来。
  • 在后台进行 API 调用。
  • 如果调用失败(极少),显示一个小的 “发送失败” 提示,并让用户重试。

我用这种模式重写了 AI 聊天功能。点击 发送 时消息立即出现,AI 的打字动画也立刻开始。后台把消息保存到数据库,但用户无需等待确认就能感受到自己的操作已生效。

结果: 天壤之别。人们不再双击 发送。功能变得响应迅速且充满活力,而不是迟钝且脱节。

删除的故事

另一个让我深有体会的场景是一个简单的 待办事项列表 功能。常规流程:

  1. 点击 删除
  2. 显示加载状态。
  3. 调用 API。
  4. 从列表中移除该项。

我改为使用乐观更新:

  • 点击 删除 → 项目立即消失。
  • API 调用在后台悄悄进行。
  • 如果调用失败,项目重新出现并弹出提示:“删除失败,请重试。”

虽然实际的 API 响应时间没有变化,但感知性能却飞涨。用户感觉交互 很快

大家常犯的错误

我最初做错的(也是很多实现中常见的)是 没有正确处理错误情况

编写成功路径很容易:

// 乐观更新,触发 API,完成

但如果调用失败且你没有保存之前的状态,就无法回滚。此时 UI 正在对用户撒谎。

这个模式需要三件事:

  1. 在做任何更改前保存当前状态。
  2. 乐观地更新 UI。
  3. 如果 API 调用 失败恢复之前的状态并通知用户。

示例(删除项目)

function deleteItem(itemId) {
  // 步骤 1:保存当前状态
  const previousItems = [...items];

  // 步骤 2:立即更新 UI(乐观)
  items = items.filter(item => item.id !== itemId);

  // 步骤 3:与服务器同步
  api.deleteItem(itemId)
    .then(() => {
      // 成功!无需其他操作
    })
    .catch(() => {
      // 失败!恢复之前的状态
      items = previousItems;
      showToast('Failed to delete item. Please try again.');
    });
}

这个模式的美妙之处在于它适用于 任何 框架——React、Vue、Angular、Svelte——因为概念相同:立即更新,随后同步,必要时回滚。

Source:

当不该使用乐观更新

在把每一个操作都设为乐观之前,先考虑哪些情况下不适合。

操作类型建议
金融交易(例如电汇)不要 乐观;等待服务器确认。
永久删除重要数据先显示确认对话框,然后对实际删除采用乐观更新。
简单可逆操作(例如点赞、切换)非常适合 乐观更新。

**经验法则:**如果操作易于撤销且失败概率低,就可以采用乐观更新;如果操作后果严重或需要确保得到确认,则等待服务器响应。

为什么这比你想象的更重要

用户并不会有意识地注意到速度快的体验;他们会感受到慢的体验。那 300 ms 的服务器等待时间?用户可能测不出具体数字,但会有迟滞的感觉。

使用乐观更新的应用会显得 原生响应迅速,好像界面在实时倾听你的操作,而不是每次呼吸都要向服务器请求许可。

  • Instagram 不会让你等到点赞显示。
  • Twitter 不会让你等到转发显示。
  • Gmail 在归档邮件时也不会让你等待(但会提供“撤销”选项以防万一)。

这些产品都明白 感知性能 与原始延迟同等重要,甚至更重要。通过在合适的场景下采用乐观更新,你可以让你的应用瞬间“活”起来。

用户之所以觉得快,是因为他们相信你的操作会成功,且把失败视为例外而非常态。

实际实现

我最初使用这种模式时,以为需要重写大量代码。结果发现,可以逐步引入。先挑选一个感觉慢的功能,给它加上乐观更新,感受一下效果。

从低风险的 点赞 按钮或简单的切换开关开始。熟悉 store → update → sync → rollback 的流程。做几次后,这套思路就会变成第二天性。

代码并不复杂,关键是思维方式的转变。你从“先请求许可,再执行”转变为“先执行,再同步”。

小结

乐观更新并不是只属于拥有庞大工程团队的大公司的一种高级技巧。它是一种简单的模式,却能显著提升应用的使用感受。

下次构建功能时,如果你发现自己要加加载指示器,问问自己:用户真的需要等吗?能否立刻展示结果并在后台同步?

大多数情况下,答案是 。用户会因此感激你,即使他们并未明确意识到为什么你的应用使用起来更顺手。

如果你觉得本文对你有帮助,我会在 LinkedIn 上分享更多实用的前端技巧和现代框架开发的真实经验。欢迎联系并分享你在乐观更新方面的实践体会。

Back to Blog

相关文章

阅读更多 »

软件质量的视角

软件质量的不同视角 软件质量——或任何产品的质量——可以从多个视角进行审视,因为不同的利益相关者带来……