{
  "id": "optimistic-ui",
  "type": "patterns",
  "status": "published",
  "name": {
    "zh": "乐观界面",
    "en": "Optimistic UI"
  },
  "aliases": [
    "Optimistic UI",
    "乐观更新",
    "乐观界面",
    "先改后等",
    "即时假成功",
    "先显示后确认"
  ],
  "category": [
    "Feedback",
    "Interaction"
  ],
  "description": {
    "zh": "用户操作后立即按\"预计成功\"更新界面，真实请求在后台进行，成功则落定， 失败则回滚到原状态并提示。它解决的是\"每个操作都要转圈等服务器\"的问题—— 用短暂的不确定换取零等待的流畅感，特别适合点赞、收藏这类高频轻操作。",
    "en": "Update the interface immediately as if the operation will succeed while the real request runs in the background; settle on success, roll back to the original state with a notice on failure. It solves the \"wait for the server on every action\" problem — trading brief uncertainty for a zero-latency feel, ideal for frequent light actions like likes and bookmarks."
  },
  "use_when": [
    {
      "zh": "点赞、收藏、关注等高频轻操作",
      "en": "High-frequency light actions — likes, saves, follows"
    },
    {
      "zh": "弱网环境下仍想保持操作流畅",
      "en": "Flaky networks where responsiveness matters"
    },
    {
      "zh": "失败可回滚且业务后果轻微",
      "en": "Failures that are safely reversible and low-stakes"
    }
  ],
  "avoid_when": [
    {
      "zh": "支付、下单等不可逆或高价值操作",
      "en": "Irreversible or high-value operations — payments, orders"
    },
    {
      "zh": "结果决定后续流程的分支走向",
      "en": "Results that decide which flow branch comes next"
    },
    {
      "zh": "回滚成本高，或回滚本身会造成困惑",
      "en": "Costly or confusing rollbacks"
    }
  ],
  "tags": [
    "feedback",
    "network",
    "interaction",
    "responsiveness"
  ],
  "variants": [
    {
      "id": "pending",
      "name": {
        "zh": "等待确认",
        "en": "Pending"
      },
      "note": {
        "zh": "乐观数值带 pending 态，请求返回后落定",
        "en": "Optimistic value carries a pending state until the request settles"
      }
    },
    {
      "id": "rollback",
      "name": {
        "zh": "失败回滚",
        "en": "Rollback"
      },
      "note": {
        "zh": "请求失败撤回更改并给出提示",
        "en": "On failure the change is reverted with a visible notice"
      }
    },
    {
      "id": "queue",
      "name": {
        "zh": "排队确认",
        "en": "Queued"
      },
      "note": {
        "zh": "连续操作依次排队，逐个确认或回滚",
        "en": "Rapid actions queue up and settle one by one"
      }
    }
  ],
  "anatomy": [
    "操作按钮（Action button）",
    "乐观数值 / 状态（Optimistic value / state）",
    "确认或回滚提示（Confirm / rollback notice）"
  ],
  "applicable_components": [
    "button",
    "toast"
  ],
  "applicable_pages": [
    "profile",
    "dashboard"
  ],
  "related": [
    {
      "id": "toast",
      "relation": "used_with"
    },
    {
      "id": "undo-action",
      "relation": "similar_to"
    },
    {
      "id": "skeleton-loading",
      "relation": "similar_to"
    },
    {
      "id": "loading-spinner",
      "relation": "used_with"
    },
    {
      "id": "button",
      "relation": "used_with"
    }
  ],
  "demo": {
    "component": "optimistic-ui",
    "modes": [
      "default",
      "dark",
      "variants"
    ]
  },
  "implementation": {
    "css": [
      "opacity transition",
      "transform scale",
      "animation",
      "keyframes"
    ],
    "notes": {
      "zh": "点击瞬间同步更新本地状态并进入 pending 态（降透明度或轻脉冲），请求返回后落定； 失败时恢复原值并弹出回滚提示。连续操作需要请求序列号防止乱序覆盖； 回滚提示可配合撤销操作。pending 动画尊重 prefers-reduced-motion。",
      "en": "Apply the local state change synchronously on click and enter a pending state (dimmed or gently pulsing); settle when the request resolves. On failure restore the previous value and surface a rollback notice. Sequence rapid requests to prevent out-of-order overwrites; pair the rollback notice with undo where relevant. Respect prefers-reduced-motion for the pending animation."
    }
  },
  "sources": [
    {
      "name": "Smashing Magazine — Optimistic UI",
      "url": "https://www.smashingmagazine.com/"
    },
    {
      "name": "web.dev — Latency and perceived performance",
      "url": "https://web.dev/articles/perceived-performance"
    }
  ],
  "prompts": {
    "basic": {
      "zh": "创建一个乐观界面（Optimistic UI）点赞按钮：点击立即 +1 并进入 pending 态， 请求成功后确认，失败自动回滚并提示。",
      "en": "Create an optimistic-UI like button where the count increments instantly with a pending state, confirms on success, and rolls back with a notice on failure."
    },
    "design": {
      "zh": "设计一个乐观更新的点赞交互。要求：点击后数值与图标立即变化并带 pending 弱化态； 成功落定为强调色；失败回滚并显示\"操作失败已恢复\"提示；提供\"模拟失败\"开关便于演示； 支持深浅色主题。",
      "en": "Design an optimistic like interaction. Requirements: value and icon change instantly with a dimmed pending state; success settles into the accent color; failure rolls back with an \"action failed, restored\" notice; include a \"simulate failure\" toggle for demonstration; light/dark themes."
    },
    "implementation": {
      "zh": "用 React + Tailwind 实现 Optimistic UI。useState 维护 liked / count / status(idle|pending|confirmed)； 点击立即翻转状态并调整数值，setTimeout 1.2 秒模拟请求：失败开关打开则回滚并设 toast， 否则落定为 confirmed；toast 2 秒后自动消失。pending 时禁止重复点击， 动画时长乘 var(--demo-speed, 1)。",
      "en": "Implement Optimistic UI in React + Tailwind. Keep liked / count / status(idle|pending|confirmed) in useState; on click flip the state and adjust the count immediately, simulate the request with a 1.2s setTimeout — if the failure toggle is on, roll back and set a toast, otherwise settle as confirmed; auto-dismiss the toast after 2s. Block re-clicks while pending and multiply animation durations by var(--demo-speed, 1)."
    },
    "agent": {
      "zh": "在当前项目中实现乐观界面（Optimistic UI）。\n\n先检查现有请求层与提示组件，优先复用现有的 toast 与按钮状态样式。\n用途：内容卡片上的点赞 / 收藏操作。\n要求：\n- 点击立即更新界面并进入 pending 态，禁止重复提交\n- 请求成功落定，失败回滚原值并给出提示\n- 连续操作用请求序号防止乱序覆盖\n- 回滚提示可配合撤销操作\n- 尊重 prefers-reduced-motion\n- 不新增不必要的依赖\n完成后运行项目现有检查，并列出修改的文件。",
      "en": "Implement Optimistic UI in the current project.\n\nInspect the existing request layer and notice components first; reuse existing toast and button state styles.\nUsage: like / bookmark actions on content cards.\nRequirements:\n- Update the interface instantly on click with a pending state; block duplicate submits\n- Settle on success; roll back to the original value with a notice on failure\n- Sequence rapid requests to avoid out-of-order overwrites\n- Pair the rollback notice with undo where relevant\n- Respect prefers-reduced-motion\n- No unnecessary dependencies\nRun existing project checks when done and list the modified files."
    }
  }
}