UX долгих задач для экспортов, импортов и AI‑заданий
UX для долгих задач повышает доверие к экспортам, импортам и AI‑операциям: понятные статусы, честные оценки ожидания и правила повтора, которые предотвращают дублирование работы.

Почему пользователи перестают доверять кнопке
Плохой UX для долгих задач часто начинается с тихого экрана.
Пользователь нажимает «Export», «Import» или «Run AI job», и ничего заметного не происходит. Нет статуса, нет оценки ожидания и нет признака, что запрос вообще дошёл до сервера.
Большинство людей не думают «система занята». Они думают, что клик не сработал. Это справедливо: многие продукты выглядят одинаково до и после начала долгой задачи.
Когда экран молчит, люди пытаются найти уверенность сами. Они кликают снова. Они обновляют страницу. Открывают другую вкладку. Закрывают ноутбук и возвращаются позже. Если задача важна, через минуту–две отправляют сообщение в поддержку.
Это не ошибка пользователя. Продукт научил их не доверять.
Когда появляется сомнение, догадки предсказуемы: «Может, я не нажал», «Может, сайт завис», «Может, началось, но я не вижу», «Может, стоит попробовать ещё раз».
Именно второй клик создаёт настоящую путаницу. Теперь вы можете получить два экспорта, два импорта или два запуска AI для одного запроса. Пользователи теряют время, а бизнес платит за дублированную работу. AI‑задачи могут сжечь токены дважды. Экспорт может поставить в очередь дубль файла. Импорт может создать повторяющиеся записи и последующую очистку.
Проблему легко увидеть на простом примере импорта. Кто‑то загружает CSV, нажимает импорт и не видит изменений в течение десяти секунд. Они обновляют страницу и отправляют файл снова. Позже приложение показывает дублированные строки клиентов. Для пользователя приложение ошиблось. Для вас оба запроса были корректны. Пробел — это интерфейс.
Доверие рушится быстро. Одного‑двух плохих случаев достаточно, чтобы люди начали зависать над кнопками, делать скриншоты или просить поддержку подтвердить «оно действительно запустилось». После этого каждая медленная задача кажется рискованной, даже если бэкенд работает как надо.
Что должен показывать экран долгой задачи
Один спиннер сам по себе никого не успокаивает. Если задача занимает больше нескольких секунд, людям нужны доказательства, что клик сработал и что система действительно выполняет работу.
Экран должен сразу ответить на пять вопросов: началась ли задача, что происходит сейчас, сколько это может занять, можно ли заниматься чем‑то другим пока ждём, и где появится результат?
Начните с мгновенного подтверждения. Измените состояние кнопки, покажите новую строку задачи или добавьте короткое сообщение вроде «Export started.» Этот маленький отклик важен. Без него люди кликают снова и создают дубликаты задач.
Используйте простой язык для статусов. «Queued» — нормально, если задача в очереди. Далее скажите, что делает система: «Uploading file», «Checking rows», «Generating report» или «Writing final CSV». Большинству пользователей не интересны детали распределения воркеров, оркестрация моделей или другие внутренние вещи.
Оценки времени должны быть приблизительными. Точные тайм‑еры выглядят умно первые десять секунд, затем начинают врать. Диапазон звучит честнее: «Обычно 2–5 минут» или «Большие импорты могут занять 10–20 минут». Если оценка меняется, обновляйте её спокойно, а не делайте вид, что ничего не произошло.
Экран также должен сказать, что безопасно делать дальше. Можно ли остаться и наблюдать? Перейти на другую страницу? Закрыть вкладку и вернуться позже? Ответ держите простым. Если задача продолжается в фоне — скажите об этом.
Затем укажите, где именно появится результат. «Your file will appear in Exports» — ясно. «Processed records will show in the customer list» — тоже ясно. Для AI‑задач скажите, попадёт ли вывод в черновики, в чат или в библиотеку ассетов.
Спокойному экрану не нужно постоянное движение. Ему нужен ясный статус, правдоподобный диапазон ожидания и одно очевидное место для результата.
Показывать время ожидания без ложных обещаний
Люди обычно больше прощают ожидание, чем неопределённость. Если экран говорит только «processing», они начинают кликать снова, обновлять страницу или просто оставлять её открытой в надежде.
Диапазон лучше, чем обратный отсчёт, когда система зависит от глубины очереди, размера файла или загрузки модели. «Обычно 2–5 минут» звучит честно. «Примерно 3 минуты осталось» кажется точным, и пользователи замечают каждую пропущенную секунду.
Если можно разделить ожидание на очередь и время работы — сделайте это. «Ожидание свободного воркера: примерно 1–3 минуты. Обработка файла: примерно 2 минуты.» Это объяснит, почему пока ничего не видно, и уменьшит желание нажать кнопку ещё раз.
Поддерживайте актуальность оценки. Когда очередь растёт, измените сообщение. Если перед пользователем появилось десять больших экспортов, диапазон 2–5 минут должен стать 5–12 минут. Двигающаяся оценка вызывает больше доверия, чем радостная ложь.
Иногда время окончания предсказать нельзя совсем. Скажите это прямо: «Мы запустили импорт. Большие файлы и медленные источники делают время завершения непредсказуемым. Вы можете уйти со страницы — мы продолжим работу.» Такое сообщение гораздо лучше, чем застрявший спиннер.
Индикаторы прогресса требуют той же честности. Не гоняйте полосу до 99% и не оставайтесь на этом месте десять минут. Люди читают это как «почти готово», даже если самый тяжёлый шаг ещё не начался. Этапы обычно работают лучше: queued, validating, processing, finalizing. Если используете прогресс‑бар — привязывайте его к реальным вехам, а не к желательной арифметике.
Несколько шаблонов сообщений, которые хорошо работают:
- «Queued now. Expected start in 1–4 minutes.»
- «Processing started. Most jobs finish in 2–5 minutes.»
- «This job has no reliable finish estimate yet. We will update status as steps complete.»
Немного честности лучше фальшивой точности. Пользователи выдерживают ожидание, когда продукт говорит, что он знает, чего не знает, и движется ли работа дальше.
Писать статусы так, чтобы их понимали люди
Людям спокойнее, когда экран говорит простыми словами. «Processing» — слишком расплывчато. Большинство пользователей хотят сразу двух фактов: что система делает сейчас и что будет дальше.
Используйте один и тот же небольшой набор состояний для экспортов, импортов и AI‑задач. Например: Queued, Running, Needs fix, Finished. Эта последовательность важнее, чем многие команды ожидают. Если на одной странице пишут «Pending», на другой «In progress», а на третьей «Working», пользователи начнут гадать, следуют ли разные задачи разным правилам.
Сопоставьте каждое состояние с одним коротким предложением о текущем действии. Это предложение должно ответить на вопрос: что система делает прямо сейчас?
- Queued — ожидает свободного воркера
- Running — генерирует ваш CSV-файл
- Running — проверяет 428 строк из вашей загрузки
- Needs fix — в строке 17 неверная дата в
start_date - Finished — отчёт готов к загрузке
Эти сообщения работают, потому что конкретны. Они не звучат технически, но при этом говорят правду.
Когда задача падает или зависает, укажите следующее действие в том же сообщении. Не ограничивайтесь «Failed» или «Error». Блокированная задача должна сказать пользователю, что делать дальше: загрузить CSV с нужными заголовками, переподключить API‑ключ, исправить отсутствующий столбец или попробовать меньший файл.
Импорты требуют больше деталей, потому что пользователи часто исправляют исходные данные самостоятельно. Указывайте точную проблему, а не общую категорию. «Import failed» порождает тикеты в поддержку. «Needs fix — row 52 is missing email» даёт путь вперёд. Если можно включить номер строки, имя столбца и короткую причину — сделайте это.
AI‑задачам нужна та же ясность. «Running — summarizing 12 documents» гораздо лучше, чем «Thinking». Если модель не может продолжить, скажите почему простыми словами: «Needs fix — the prompt is empty» или «Needs fix — the source file could not be read». Этого достаточно.
Чёткий текст статуса делает огромную работу. Он уменьшает повторные клики, сокращает обращения в поддержку и помогает пользователям доверять, что кнопка сработала.
Построить безопасное поведение retry
Повторы должны «подхватывать» пользователя к той же работе, а не тихо запускать вторую копию. Когда это ломается, пользователи кликают ещё, открывают другую вкладку или пишут в поддержку, потому что не понимают, что уже произошло.
Решение начинается до того, как на экране появится прогресс. Сохраните задачу в момент клика. Дайте ей ID, сохраните параметры запроса и пометьте как queued или running сразу. Если страница перезагрузится через две секунды, у вас всё ещё будет реальная задача, которую показать.
Простой поток работает хорошо:
- Когда пользователь нажимает Start — сначала создайте задачу и верните экран её статуса.
- После первого клика измените текст кнопки с Start на View status.
- Если приходит тот же самый повторный запрос — откройте существующую задачу вместо создания новой.
- Если задача упала, укажите, возобновит ли retry тот же прогон или начнёт новый.
- Держите сообщение об ошибке и действие retry на одном экране.
Второй шаг важнее, чем кажется. «View status» говорит пользователю, что система его услышала. Это также даёт безопасное место, куда вернуться после обновления, краха браузера или потери соединения.
Повторное использование той же задачи при повторных запросах — то, что останавливает дублирование экспортов, импортов и AI‑запусков. Сопоставляйте запросы по тому, что делает их одинаковыми в вашем продукте: тот же пользователь, тот же файл, те же настройки или тот же prompt. Если ничего не изменилось — откройте существующую задачу.
Правила retry должны быть простыми. «Retry safely» достаточно для экспорта, который перестраивает файл. Импорт — другое дело. Если повтор может добавить строки дважды, скажите об этом до того, как пользователь нажмёт. Для AI‑задачи честно укажите, создаст ли retry новый результат или снимет оплату ещё раз.
Сделайте восстановление удобным на одном экране. Покажите ошибку, что было сделано до сбоя и следующий шаг вместе. Пользователь не должен читать тосты об ошибках, искать старую задачу и гадать, какая кнопка безопасна.
Лучший поток retry кажется скучным. В этом и смысл.
Три примера из загруженного утра
Представьте понедельник утром с тремя одновременно работающими задачами. Люди заняты, немного нетерпеливы и не хотят нажимать одну и ту же кнопку дважды, чтобы почувствовать себя спокойнее.
Менеджер по продажам запускает экспорт за десять минут до встречи. Сразу после клика экран меняется на «Export started» и показывает ID задачи, приблизительное время «примерно 2–4 минуты» и простое указание: «You can stay here or leave this page. We will keep building your file.» Кнопка становится неактивной, рядом со статусом появляется спиннер, и менеджер перестаёт переживать, что запрос пропал.
Операционный коллега загружает импорт клиентов на 4200 строк. Система сначала сканирует файл, затем говорит: «Import running. 4 rows need attention.» Вместо расплывчатой ошибки в конце экран показывает прогресс, приблизительную оценку «примерно 6 минут» и одно чёткое следующее действие: «You can download the problem rows and retry only those rows after you fix them.» Коллеге не надо перезапускать весь импорт. Он знает, что упало, что прошло и что делать дальше.
Маркетолог запускает AI‑резюме большой пачки заметок звонков. Эта задача может занять дольше, и время сильнее плавает, чем у экспорта. Поэтому сообщение остаётся честным: «AI summary in progress. Most batches this size finish in 8–15 minutes.» Экран также может сказать, что система делает сейчас, например «Reading notes» или «Writing summaries.» Если какие‑то заметки таймаутнут, следующий шаг будет конкретным: «23 summaries are ready. Retry 5 failed notes.» Это гораздо лучше полного перезапуска.
Все три потока следуют одному шаблону. Покажите, что клик сработал. Покажите текущий статус. Покажите приближённое ожидание, а не выдуманное обещание. Покажите следующее действие, которое пользователь может сделать прямо сейчас.
Когда команды это делают правильно, обращения в поддержку падают по очень обычной причине: пользователи перестают спрашивать «Оно началось?». Они и так знают.
Ошибки, которые создают дубли и обращения в поддержку
Большинство дублирующих задач начинаются не из‑за нетерпения, а из‑за неопределённости. Кто‑то нажимает «Export», видит спиннер без текста и думает, что ничего не произошло. Через несколько секунд он кликает снова, открывает другую вкладку или обновляет страницу.
Пустой спиннер быстро порождает сомнения. Пользователям нужно простое сообщение вроде «Preparing your file» или «Importing 2,400 rows.» Ещё лучше — показать задачу в видимой очереди или панели истории, чтобы люди видели, что система зафиксировала их действие.
Фальшивое движение создаёт другую проблему. Если полоса прогресса движется, а на самом деле ничего не меняется, пользователи перестают доверять экрану. Показывайте реальный процент только тогда, когда система может измерить реальный прогресс. Иначе показывайте текущий шаг и простой статус вроде «Still working» или «Waiting for processing to finish.»
Обновление страницы не должно перезапускать задачу. Если пользователь перезагружает страницу после начала экспорта, продукт должен переподключиться к той же задаче и показать её текущее состояние. Когда перезагрузка запускает второй экспорт, импорт или AI‑запуск — пользователи получают дубли, а поддержка — грязные тикеты.
Команды также теряют доверие, когда показывают «Finished» слишком рано. Успех должен означать, что файл существует, результаты импорта готовы к проверке или AI‑вывод можно открыть прямо сейчас. Если системе ещё нужно сохранить файл или финализировать результат — скажите об этом.
Сообщения об ошибках часто всё портят. «Something went wrong» почти ничего не объясняет. Лучше сообщить, что именно упало, идёт ли первоначальная задача дальше, и дать одно следующее действие: retry, подождать или связаться с поддержкой и привести ID задачи.
Пользователи могут ждать дольше, чем думают многие команды. Им просто нужно, чтобы продукт говорил правду.
Быстрые проверки перед релизом
Нужен не огромный план QA, а короткий проход, который копирует поведение реальных людей, когда экспорт, импорт или AI‑задача занимает дольше, чем ожидалось.
Пройдите поток как нетерпеливый пользователь, а не как разработчик:
- Обновите страницу, пока задача ещё выполняется. Та же задача должна отображаться с тем же статусом.
- Закройте вкладку, подождите минуту и вернитесь. Статус должен остаться и иметь смысл.
- Запустите ту же задачу дважды. Нажмите дважды быстро, нажмите Enter ещё раз или откройте вторую вкладку. Система должна сохранить один прогон или ясно сказать, что он уже в процессе.
- Намеренно сломайте импорт. Добавьте одну плохую строку в файл и проверьте текст ошибки. «Row 18: email is missing» помогает. «Validation failed» — нет.
- Прочтите вслух каждое сообщение статуса. Если оно звучит как серверный жаргон — перепишите.
Эти проверки небольшие, но быстро показывают слабые места. Задача, которая переживает обновление и закрытие вкладки, кажется надёжной. Задача, которая блокирует дубли — безопасна. Упавший импорт с точной ошибкой — исправим.
Если хотя бы одна из этих проверок ломается, пользователи начинают гадать. Они пытаются повторить, создают дубли и пишут в поддержку «Я нажал кнопку, но ничего не произошло». Исправить это до релиза дешевле, чем разгрёбать запутанные задачи потом.
Следующие шаги для вашей команды
Поставьте весь поток задач на одну страницу до того, как менять продукт. Многие команды держат детали разбитыми по дизайн‑файлам, заметкам бэкенда и документации поддержки, и никто не видит полный путь пользователя. Выпишите каждое состояние, которое может увидеть человек: queued, starting, running, delayed, done, failed, canceled, retrying и всё между.
Эта простая карта обычно быстро выявляет грязные места. Вы увидите экраны без статуса, задачи, которые падают молча, и кнопки, которые всё ещё выглядят кликабельными, когда работа уже идёт.
Затем запустите три реальных проверки от начала до конца: один экспорт, один импорт и одну AI‑задачу. Используйте обычные аккаунты, без обходных путей. Следите, что видит пользователь после каждого клика, насколько долго кажется ожидание, что происходит при обновлении страницы и может ли пользователь отличить «ещё работает» от «застрял».
Короткий обзор обычно покрывает достаточно:
- Сравните видимые состояния с реальными состояниями бэкенда.
- Проверьте, остаётся ли сообщение об ожидании правдоподобным со временем.
- Испробуйте поведение retry после задержки, потери сети и обновления браузера.
- Убедитесь, что пользователь может найти результат, ошибку или следующее действие без обращения в поддержку.
После этого читайте тикеты поддержки и логи чатов с одним вопросом: где люди перестали доверять кнопке? Ответ обычно конкретен. Они нажали дважды, потому что ничего не изменилось. Они повторили, потому что первая задача исчезла. Они ждали двадцать минут, потому что страница никогда не сказала, что файл готов.
Исправьте эти моменты в первую очередь. Небольшие изменения обычно важнее редизайна. Чёткое состояние «ещё обрабатывается», реальное правило retry или видимая история задач могут очень быстро сократить дубли и обращения в поддержку.
Если поток пересекает продукт, бэкенд и поддержку — дайте одному человеку ответственность за модель состояний. Иначе каждая команда латает свою часть, а пользователь получает смешанные сигналы.
Если хотите внешний обзор, Oleg Sotnikov at oleg.is может просмотреть модель состояний, правила retry и точки передачи как Fractional CTO. Это полезно, когда проблема не в одном экране, а в том, как вся система ведёт себя под реальной нагрузкой.
Хороший результат легко заметить. Пользователи нажимают один раз, понимают ожидание и знают, что делать дальше.
Часто задаваемые вопросы
Как показать, что нажатие кнопки сработало?
Покажите мгновенное изменение. Отключите кнопку, измените её подпись или откройте строку задачи с коротким сообщением вроде Export started. Этот мгновенный ответ показывает, что запрос дошёл до сервера и уменьшает повторные клики.
Достаточно ли только спиннера для долгой задачи?
Один только спиннер редко помогает, если задача длится больше нескольких секунд. Сопровождайте его простым текстом статуса, приблизительным диапазоном ожидания и указанием, где появится результат. Если можно, показывайте реальные этапы: queued, validating, running, finalizing — это успокаивает пользователей.
Какое время ожидания лучше показывать?
Показывайте приблизительный диапазон, а не обратный отсчёт. «Обычно 2–5 минут» звучит честно и даёт пользователю полезное ожидание без ложной точности. Если очередь растёт или система замедляется, обновите диапазон вместо того, чтобы оставлять старую оценку.
Какие метки статуса работают лучше всего?
Держите состояния короткими и последовательными по всему продукту. Метки вроде Queued, Running, Needs fix и Finished работают хорошо — пользователи быстро их запоминают. Под каждой меткой добавляйте одно простое предложение о том, что система делает сейчас.
Что должно происходить при обновлении страницы?
Переподключайте пользователя к той же задаче. Сохраните задачу сразу после клика, присвойте ей ID и при перезагрузке снова загрузите эту задачу. Если перезагрузка запускает вторую пару, пользователи перестанут доверять потоку действий.
Как предотвратить дублирование задач?
Создайте задачу сначала, а затем обрабатывайте повторные клики как запрос на существующую задачу, если ничего не изменилось. Повторно открывайте существующую задачу вместо создания новой. Изменение кнопки с Start на View status тоже направляет пользователя в безопасный путь.
Что должно содержать сообщение об ошибке?
Скажите, что именно пошло не так, сохраняется ли первоначальная задача и что делать дальше. Row 18 is missing email помогает гораздо больше, чем Validation failed. Для AI-задач и экспортов укажите, возобновит ли повтор тот же прогон или начнётся новый.
Как должен работать retry для экспорта, импорта и AI-задач?
Повтор должен быть предсказуемым и безопасным. Для экспортов повтор часто просто перестроит файл и риск невелик. Для импортов повтор может добавить строки дважды — предупредите об этом. Для AI-задач повтор может создать новый результат или повлечь оплату — скажите это заранее.
Можно ли уходить со страницы, пока задача выполняется?
Да, если задача продолжает выполняться в фоне — скажите это простыми словами. Сообщите, что можно уйти со страницы и вернуться позже, и укажите, где появится результат. Это снимает много нервного ожидания.
Что команда должна протестировать перед релизом?
Тестируйте поток как нетерпеливый пользователь: обновите страницу во время выполнения, закройте вкладку и вернитесь, нажмите кнопку дважды быстро и поломайте импорт добавлением одной плохой строки. Прочтите вслух все сообщения статуса и замените серверный жаргон простыми словами.