写“保存”按钮时,我最顺手的做法是一点下去就转圈,同时把文字换成“保存中…”。可网速快的时候,请求几十毫秒就回来了,这个转圈只存在一眨眼,按钮还跟着变宽又变回来。用户看到的不是“正在保存”,而是按钮闪了一下,像出了什么故障。
✕ 一点就转
昵称Joye
简介写代码,也写字。
已保存
点“保存”,看看转圈什么时候出现、停留多久。
选“快”,连点几次左边的保存:转圈和“保存中…”一闪就没,按钮还跟着变宽又变回来,像出了故障。
✓ 晚 200ms 再转,转了就至少停 400ms
昵称Joye
简介写代码,也写字。
已保存
点“保存”,看看转圈什么时候出现、停留多久。
同样是“快”,右边一下都不转,直接显示已保存。切到“一般”,转圈会出现,但至少停留 400ms,不会一闪而过。
01先等一下再转。很快就回来的请求不需要转圈,等 150–300ms 还没回来,再告诉用户“正在处理”。
02转了就多留一会儿。一旦出现,至少停留 300–500ms,否则它刚出现就消失,看起来还是闪了一下。
03按钮保留原来的文字。只把图标换成转圈,按钮宽度不变,旁边的东西也不会跟着跳。
为什么这样更好#
- 太快的转圈读起来像故障。转圈只露面几十毫秒,眼睛来不及认出它是什么,只觉得界面抖了一下。
- 先等一下,快请求就不打扰人。大约 200ms 内回来的请求,直接给结果;超过这个时间还没回来,才说明真的需要等,这时再显示转圈。
- 转了就别马上收。如果转圈刚出现请求就回来了,立刻收起又是一次闪烁。给它一个最短停留时间,出现了就完整地转一会儿。
- 按钮文字不要换。把“保存”换成“保存中…”,按钮宽度会变,旁边的元素跟着挪动。只把图标换成转圈,按钮还是那个按钮,人也知道自己点的是什么。
- 代价很小。最坏的情况是请求刚好在转圈出现后回来,结果要多等不到 400ms 才显示;换来的是快的时候干干净净,慢的时候有稳定的反馈。
骨架屏、局部的加载占位也是同样的道理:它们出现得太早、消失得太快,一样会闪。
什么时候不该用#
- 操作本身就需要立刻反馈,比如拖拽、输入时的实时校验,等 200ms 会让人觉得没反应。这类场景应该先乐观地更新界面,而不是转圈。
- 已知一定很慢的任务(上传大文件、生成报告),一开始就应该显示进度,没必要再延迟。
- 按钮在请求期间必须防止重复提交时,即使转圈还没出现,也要先把重复点击挡住。延迟的只是“显示”,不是“状态”。
出处#
来自 Vercel 的 Web Interface Guidelines ↗。交互一节里有两条:加载中的按钮要“显示加载指示,并保留原来的文字”;显示转圈或骨架屏时,加一个约 150–300ms 的显示延迟和约 300–500ms 的最短显示时间,避免快速响应时的闪烁。demo 里取的是 200ms 和 400ms。