Skip to content
PПромтбук
RUEN
02UX-флоу

Autosave: спецификация UX

Когда сохранять (debounce / blur / interval), как индицировать (saved / saving / error), conflict resolution. Без «иногда теряется, мы исследуем».

Действуй как product engineer. Autosave — это не «таймер каждые 5 секунд». Это контракт с юзером на то, что его работа не пропадёт. Контракт нужно сделать видимым, иначе юзер не доверяет.

Контент: {{content_type}} Совместность: {{collaboration}} Критичность данных: {{data_criticality}}

Закон autosave: 3 уровня доверия

УровеньЧто юзер видитКогда уместен
ТихийНичего. Просто сохраняется.Никогда. Юзер не доверяет тишине.
Status indicatorМаленький текст «Saved» / «Saving...» / «Error»Стандарт. 95% случаев.
Full UI feedbackToast при save, иконка изменений, undo timelineCritical-data, collaborative editing.

Триггеры сохранения (не выбирай один — комбинируй)

Debounce on change

  • 500-800ms после последнего keystroke — стандарт для текста.
  • На blur — сразу, без debounce.
  • На action (drag-drop, toggle, выбор) — сразу.

Интервал (safety net)

  • Каждые 30-60 секунд — fallback, если debounce не сработал (например, юзер замер в поле).

На событиях

  • Window blur / page hide — сразу save (юзер уходит).
  • Перед navigation — sync save с beforeunload (если есть unsaved).
  • На submit / explicit save — финальный save с подтверждением.

Индикация: статусы

СтатусТекстИконкаАнимация
Sync'ed (default)«Saved» или «All changes saved»check (subtle grey)none
Saving«Saving...»spinner (small)в течение save
Saved (just now)«Saved» + время «2s ago» (3 сек, затем fade в default)check (briefly accent)brief pulse
Error«Couldn't save. [Retry]»warning (red)none
Offline«Offline. Changes will sync.»cloud-offnone
Conflict«Updated by Alex. [Review changes]»merge iconattention-grabbing

Расположение: top-right в header документа, или внизу editor'а. Не toast для каждого save — будет спам.

Conflict resolution

Single user, multi-device

  • Last-write-wins с момента изменения. Если на устройстве A был более свежий save, чем на B — A выигрывает.
  • При open document — pull latest state. Если local есть unsaved — diff и предложить resolve.
  • Visual: badge «You have unsaved changes on this device» + buttons «Use local / Use server».

Multi-user collaborative

  • OT / CRDT (operational transform / conflict-free replicated data types) — для текста.
  • Optimistic locking — для структурных данных (server проверяет version-number, отказывает если конфликт).
  • Visual feedback: «Updated by Alex 2s ago» badge при изменении другим юзером.
  • Conflict UI: show diff inline с кнопками «Keep mine / Keep theirs / Merge».

Offline → online

  • Local queue изменений.
  • При reconnect — push queue, обрабатывать conflicts по правилам выше.
  • Long offline → manual reconcile dialog: «You have 8 unsaved changes from offline. Review?»

Error handling

Транзиентные (network blip)

  • Retry с exponential backoff: 1s, 2s, 4s, 8s, 16s.
  • В UI: «Saving... (retry 2 of 5)».
  • После 5 неудачных — «Save failed. [Retry] or [Download changes]».

Постоянные (server 500, permission denied)

  • Стоп autosave.
  • UI: «Couldn't save. <reason>. [Retry] [Export local copy]».
  • Не теряй local state — храни в localStorage с time-out 24h.

Quota / size exceed

  • Pre-flight check (если content > N MB → warning перед save).
  • При ошибке: «File too large to autosave. Please <split / export / etc.>».

Granularity

  • Document-level: весь документ → один save. Просто, но дорого при больших документах.
  • Field-level: только изменённое поле. Лучше для структурных данных, форм.
  • Operation-level: каждое действие как событие (best для collab — Figma, Notion model).

Выбор зависит от content_type:

  • Text editor → operation-level (для performance) или document-level (для простоты).
  • Form / config → field-level.
  • Drawing → operation-level.

Undo + autosave

  • Autosave не отменяет undo history.
  • Undo возвращает к pre-edit state, save сохраняет это новое (отмененное) состояние.
  • Time-travel: «Restore to 5 min ago» — если есть versioning.

Visibility: «вы видите свои изменения»

После любого autosave — UI не должен мигать. Юзер не видит save, только статус-индикатор. Не должно быть:

  • Перерисовки документа после save.
  • Loss of focus / scroll position.
  • Loss of selection.

A11y

  • Статус-индикатор — aria-live="polite". «Saved» зачитывается screen reader-ом без перебивания.
  • Error — aria-live="assertive" + role="alert".
  • Кнопка retry — нативная <button> с понятным aria-label.
  • Conflict UI — focusable, можно навигировать клавиатурой.

Формат вывода

Решение по триггерам

  • Debounce: X ms
  • Interval safety net: Y sec
  • На событиях: список

Индикатор

  • Расположение
  • Текст для каждого статуса (точные формулировки)
  • Иконка для каждого
  • Поведение (когда меняется, как долго показывается)

Conflict-стратегия

  • Single user / multi-device: ...
  • Multi-user collab: ...
  • Offline reconcile: ...

Errors

  • Транзиентные: retry policy
  • Постоянные: UI + local backup
  • Quota: pre-flight + error

Granularity

  • Document / field / operation
  • Почему этот выбор

Visibility rules

Что юзер должен / не должен видеть после save.

A11y

ARIA + announce.

Anti-patterns (НЕ делать)

  • ❌ Save без индикации. Юзер не доверяет.
  • ❌ Toast «Saved» на каждое сохранение. Спам, юзер ослепнет.
  • ❌ Save только на blur. Юзер копит часовую сессию в одном поле — refresh теряет всё.
  • ❌ Save без offline-fallback. Wi-Fi моргнул → save error → юзер бросает.
  • ❌ Conflict «Кто-то изменил документ. Перезагрузите» — теряются local changes.
  • ❌ Перерисовка после save. Юзер видит мигание — думает, что что-то сломалось.
  • ❌ Generic «Save failed» без reason. Юзер не понимает, можно ли retry.
  • ❌ Localstorage-only без server sync на critical data. Закрылся браузер — потерял.
  • ❌ Save после navigation, без beforeunload. Юзер уходит → данные не сохранились → жалоба.
К подразделу «UX-флоу»
Похожие промты