核心觀念

回饋的形式取決於等待時間 — loading spinner 只適合中間帶的等待。100ms 的頁面切換和 30 秒的批次匯出需要的指示完全不同:前者加 spinner 是視覺雜訊、讓操作顯得比實際慢,後者只有 spinner 撐不住使用者的耐心、他需要知道還要等多久。

設計回饋策略的依據是人類對時間的主觀感知 — 不同的等待長度會觸發不同的心理反應。本篇展開三層回饋模型第二層「等待指示」(三層=點擊確認 / 等待指示 / 結果通知)的策略選擇。

時間門檻

這些門檻來自兩個量測對象不同的研究框架:100ms / 1s / 10s 是感知與注意力門檻(Miller、Nielsen)、400ms 是生產力門檻(Doherty)。本篇把兩者合併在同一條時間軸上使用 — 設計決策關心的是「等多久該給什麼回饋」,兩個框架在這個問題上給出互補的分段點。

100ms — 即時感知門檻

來源:人類感知研究(Miller, 1968; Card, Moran & Newell, 1983)。

100ms 以內的延遲被感知為「即時」。使用者不會注意到任何等待,操作感覺像是直接發生。

設計策略:第一層的點擊確認(視覺狀態變化)就足夠,無需額外等待指示。

適用:同步操作(導航、切換、本地計算)。

400ms — Doherty Threshold

來源:Doherty & Thadani, “The Economic Value of Rapid Response Time”(IBM 技術報告, 1982)。

原始研究發現:當電腦回應時間低於 400ms 時,使用者的操作效率大幅提升 — 人機互動進入一種「流暢循環」,雙方都不需要等對方。超過 400ms,這個循環被打斷。

設計策略:400ms 以內完成的操作可省略 loading indicator — 把生產力門檻讀成回饋門檻是 Laws of UX 等現代整理的轉譯、本篇沿用。可以用動畫過渡(fade in、slide)讓結果「出現」而非「替換」,利用動畫時間掩蓋等待感。

適用:快速 API 回應、本地資料庫查詢、簡單計算。

1 秒 — 心流維持門檻

來源:Nielsen’s response time limits(Usability Engineering, 1993)。

1 秒以內,使用者的思考流程不會被打斷。雖然能感知到延遲,但不會覺得「系統卡住了」。

設計策略:開始顯示輕量級等待指示。按鈕進入 loading 狀態(spinner 取代文字)。但不需要進度百分比或預估時間。

適用:一般 API 請求、檔案讀寫、中等複雜度查詢。

10 秒 — 注意力維持上限

來源:Nielsen’s response time limits(同上)。

超過 10 秒,使用者開始考慮離開。注意力已經從當前操作轉移到是否放棄的權衡上。

設計策略:必須提供進度指示(百分比 / 步驟計數 / 預估剩餘時間),讓使用者判斷「還值不值得等」。考慮提供取消操作的選項。操作再長(數十秒以上)考慮轉為背景任務、完成後由通知系統告知 — 通知系統設計在本篇範圍外。

適用:檔案上傳、批次處理、大型資料同步。

策略對照表

等待時間使用者感受回饋策略範例
0-100ms即時點擊確認即可頁面導航、開關切換
100-400ms幾乎即時動畫過渡掩蓋等待快速搜尋、本地查詢
400ms-1s短暫等待Spinner / loading 狀態API 查詢、表單送出
1-10s明顯等待進度指示 + spinner檔案上傳、資料匯入
> 10s長時間等待進度百分比 + 預估時間 + 取消選項批次處理、大型同步

門檻怎麼落地:延遲是分布不是常數

策略對照表把「等待時間」當成單一數值,但真實延遲是分布:同一支 API 平常 300ms,尖峰或弱網下 3s。發出請求前無法知道這一次會落在哪一帶,照表選策略需要兩個補充機制。

用高百分位對表,不用平均值:對表的統計量取 p90 或 p95(應用效能監控(APM)平台或瀏覽器 DevTools 的 Network 面板都查得到)。平均 300ms、p95 卻 2s 的操作,代表每二十次就有一次使用者盯著沒有任何指示的畫面等 2 秒 — 對表要照顧的是這些請求,不是平均值。

延遲顯示與最短顯示時間:防 spinner 閃爍

延遲顯示(delayed spinner):發出請求後先不顯示 spinner,等 300-400ms 才掛上;請求先回來就完全不顯示。快的請求(多數)沒有 spinner 閃爍,慢的請求(少數)在使用者開始懷疑之前得到指示。這是延遲分布橫跨門檻帶時的標準解 — 判準從「這支 API 多快」變成「超過 400ms 才需要告訴使用者」。

最短顯示時間(minimum display time):spinner 一旦顯示就至少停留一段時間(常見慣例值 300ms),請求提早完成也不立即移除,消除「spinner 閃一下就消失」的視覺雜訊。

延遲顯示的 300-400ms 與最短顯示的 300ms 都是業界慣例值、不是研究門檻,可依產品實際延遲分布調整。原則是顯示決策跟著使用者的感知走、不跟著單次請求的實際時長走。

延遲分布策略
p90 < 400ms延遲顯示 spinner(多數使用者不會看到它)
p90 400ms - 1s按鈕 loading 狀態 + 最短顯示時間
p90 1 - 10s進度指示
跨帶(p50 與 p95 差一個帶以上)以 p95 所在帶設計 UI、加延遲顯示讓快的請求不受擾

驗證方式:用瀏覽器 DevTools 的網速節流(或 proxy 限速)模擬慢回應,逐帶確認對應的 UI 真的會出現;沒有節流工具時,暫時在 client 加人工延遲也能達到同樣目的。

感知效能技巧

真實效能無法改變時(伺服器就是要跑 3 秒),可以透過設計降低使用者的等待感受:

骨架畫面(Skeleton Screen)

在資料載入前先顯示內容區域的灰色佔位形狀。使用者看到「畫面結構」比看到空白等待更不焦慮。適合列表、卡片等有明確版面的內容。佔位尺寸要與最終內容一致 — 載入完成瞬間的版面跳動(layout shift)比空白等待更傷體驗,會抵銷 skeleton 的全部收益。

Spinner vs Skeleton:形狀已知用 skeleton、未知用 spinner

Spinner 和 Skeleton Screen 都是等待指示,但適用場景不同。選錯會降低使用者體驗。

條件SpinnerSkeleton Screen
結果形狀已知(列表 / 卡片 / 個人資料)適合:佔位形狀接近最終結果,降低焦慮
結果形狀不確定(連線結果 / 計算結果)適合:無法預畫佔位形狀
操作觸發的等待(按下按鈕後)適合:按鈕內 spinner
頁面首次載入(進入新畫面)適合:給畫面結構預期
等待時間短且可預測(< 2s)適合:輕量指示
等待時間較長(2-10s)適合:佔位結構降低空白等待的焦慮

判斷口訣:「知道長什麼樣 → skeleton;不知道 → spinner。」

表中三個條件軸(形狀、觸發方式、時長)可能同時命中不同建議,裁決順序是形狀 > 觸發 > 時長。例:按下按鈕載入個人資料、預期 1.5s — 形狀已知(個人資料版面固定)就用 skeleton,即使「操作觸發」那列寫 spinner。觸發方式與時長只在形狀軸分不出勝負(形狀部分已知、或混合內容)時才進入裁決。

表中 2s 的分界是切分用的慣例值、不在研究門檻系裡。1-10s 帶跟策略對照表的「進度指示」建議並不衝突 — 內容載入走 skeleton、操作進度走進度指示,正是形狀軸裁決的結果。

樂觀更新(Optimistic Update)

在伺服器回應前先更新 UI,假設操作會成功。如果失敗再回滾。適合高成功率的操作(按讚、收藏、勾選)。風險:失敗回滾時,使用者看到剛完成的操作被悄悄還原、會開始不信任介面 — 回滾因此要走三層回饋模型的失敗通知:明確告知「操作未成功、已還原」加上下一步(重試),讓還原是被告知的結果、不是無聲消失。

漸進式載入(Progressive Loading)

先載入最重要的內容(文字),再載入次要內容(圖片、評論)。使用者可以在等待期間開始閱讀,降低「什麼都不能做」的焦慮。

動畫過渡

用動畫填充短暫的等待時間。300ms 的 fade-in 動畫可以掩蓋 200ms 的 API 延遲,使用者感知到的是「動畫」而非「等待」。

不要做的事

反模式為什麼不好
每個操作都顯示全螢幕 loading阻斷所有互動,打斷心流
spinner 顯示後立即消失(閃爍)視覺雜訊,比不顯示更差
進度條從 0% 跳到 100%失去進度指示的意義
假進度條(與實際進度無關)被識破後失去信任
Loading 永不消失(無 timeout)介面凍結,使用者只能殺 app

進度條類的反模式共享一個根因:進度指示的價值在於讓使用者校準預期,指示與實際脫鉤(假進度、0% 跳 100%)時信任一次性崩壞。拿不到真實進度時,用步驟計數(「3 / 5 個檔案」)或 indeterminate 動畫誠實表達「在跑、但無法預估」,優於編造百分比。

完成宣告的誠實度與進度指示同源。「完成」的判定條件若只是「連續 N 輪沒有變化」,分不出「真的到底了」和「載入通道根本沒打開」— 一個 Chrome extension 從 lazy-load 頁面提取書目,96/928 本就因 count 穩定誤判完成,使用者帶著殘缺資料離開且很難察覺(U.C11)。宣告完成要有窮盡證據(總數對照、終止標記、API 側的分頁 cursor 耗盡);只有停滯訊號時,改為「已取得 N 筆、可能還有更多」的部分結果表達 — 下游需要全量的操作(備份、匯出)不適用降級、不完整按失敗處理。全螢幕 loading 的問題則是阻斷範圍 — 等待指示只需要覆蓋被等待的區域,不需要凍結整個介面。

設計檢查清單

  • 操作的延遲分布(p90 / p95)是多少?對應哪個門檻帶?(跨帶判定另看 p50)
  • 低於 400ms 的操作:不顯示 spinner,用動畫過渡?
  • 400ms-1s 的操作:有按鈕 loading 狀態?
  • 超過 1s 的操作:有進度指示?
  • 超過 10s 的操作:有取消選項?
  • 有考慮感知效能技巧(骨架畫面 / 樂觀更新 / 漸進載入)?
  • spinner 有延遲顯示與最短顯示時間(防閃爍)?
  • 用 DevTools 網速節流(或 proxy 限速)模擬慢回應,驗證各門檻帶的 UI 都會出現?

參考來源

  • Doherty, W.J. & Thadani, A.J. “The Economic Value of Rapid Response Time.” IBM, 1982(技術報告)— 400ms 門檻的原始研究
  • Nielsen, J. Usability Engineering. Academic Press, 1993 — 100ms / 1s / 10s 三門檻模型
  • Card, S.K., Moran, T.P. & Newell, A. The Psychology of Human-Computer Interaction. Lawrence Erlbaum Associates, 1983 — 人機互動的認知心理學基礎
  • Miller, R.B. “Response Time in Man-Computer Conversational Transactions.” Proceedings of the AFIPS Fall Joint Computer Conference, 1968 — 回應時間對使用者行為影響的早期研究
  • Material Design 3: Loading Indicatorm3.material.io/components/loading-indicator)— Google 的 loading 設計規範
  • Laws of UX: Doherty Thresholdlawsofux.com/doherty-threshold)— Doherty Threshold 的現代詮釋