Pull to refresh
159.7
JUG Ru Group
Конференции для Senior-разработчиков

Правдивая ложь оптимистичных интерфейсов

Reading time 14 min
Views 19K
Original author: Денис Мишунов
Недавно опубликованная в Smashing Magazine статья Дениса Мишунова показалась нам очень интересной: она посвящена подходу, о котором многие до сих пор не задумываются, хотя он уже окружает нас в популярнейших сервисах. С разрешения автора и первоисточника мы решили перевести этот материал для хабрасообщества.

Три пользовательских интерфейса заходят в паб. Первый заказывает напиток, затем ещё несколько. Парой часов позже он просит счёт и покидает паб пьяным. Второй заказывает напиток, платит за него сразу же, заказывает ещё один, платит за него, продолжает в том же духе, и через пару часов покидает паб пьяным. А третий заходит в паб уже пьяным — он знает, как работают пабы, и достаточно эффективен, чтобы не терять время. Слышали об этом третьем? Его называют «оптимистичным UI».



Оптимистичный подход к UI не в том, чтобы смотреть на веб через розовые очки — по крайней мере, не только в этом.

В последнее время, обсуждая психологическую оптимизацию производительности на целом ряде конференций, посвящённых как фронтенду, так и UX, я заметил, как мало внимания в сообществе уделено теме оптимистичных интерфейсов. Даже сам термин «оптимистичный UI» не слишком хорошо определён. В этой статье мы разберёмся, на каких концепциях он основан, и посмотрим на примеры, а также разберёмся с его психологическим обоснованием.

Но прежде чем мы начнём, надо признать: «оптимистичным UI» нельзя назвать что-то конкретное. Скорее, это ментальная модель, стоящая за внедрением интерфейса. У оптимистичного UI есть своя история и своё логичное обоснование.

Однажды давным-давно


Когда-то давно — когда слово «tweet» применяли в основном к птицам, Apple была на грани банкротства, а люди помещали на свои визитки номера факсов — веб-интерфейсы были довольно аскетичными. И подавляющее большинство из них было лишено даже намёка на оптимизм. Взаимодействие с кнопкой, например, могло следовать по такому сценарию:

  1. Пользователь нажимает на кнопку.
  2. Кнопка меняет состояние на деактивированное.
  3. Запрос отправляется на сервер.
  4. Ответ от сервера направляется обратно на страницу.
  5. Страница перезагружается для отображения результатов ответа.




В 2016-м это может показаться очень неэффективным, но, как ни удивительно, тот же сценарий по-прежнему используется большим количеством веб-страниц и приложений, являясь неотъемлемым элементом взаимодействия для многих продуктов. Причина в том, что этот тип взаимодействия предсказуем и более-менее защищён от ошибок: пользователь знает, что действие было запрошено от сервера (деактивированное состояние кнопки намекает на это), и когда сервер отвечает, обновлённая страница явно свидетельствует об окончании взаимодействия «клиент-сервер-клиент». Проблемы с этим типом взаимодействия довольно очевидны:

  • Пользователь должен ждать. А мы уже знаем, что даже небольшая задержка во времени ответа негативно отражается на восприятии пользователем всего бренда, а не только конкретной страницы.

  • Каждый раз, когда пользователь получает ответ на свои действия, это происходит довольно деструктивно (загружается новая страница вместо обновления уже существующей), что изменяет контекст пользовательской задачи и может сбить с мысли. Пусть речь в этом случае не обязательно идёт о многозадачности, любое переключение мыслительного контекста неприятно. Так что, если только само действие не подразумевает неизбежную смену контекста (онлайн-платежи — хороший пример такой смены), переключение задаст негативный тон общению пользователя с системой.

Не-такие-уж-старые добрые времена


Затем появился так называемый Web 2.0, предоставив новые способы взаимодействия с веб-страницами. Их основой стали XMLHttpRequest и AJAX. Эти новые способы дополнились «спиннерами»: простейшей формой индикации прогресса, единственная задача которой — донести до пользователя, что система работает над какой-то операцией. Теперь нам не надо было перезагружать страницу после получения ответа от сервера, мы могли просто обновить часть уже отрендеренной страницы. Благодаря этому веб стал динамичнее, а пользовательское взаимодействие стало происходить более гладко. Типичное взаимодействие с кнопкой теперь могло выглядеть так:

  1. Пользователь нажимает на кнопку.
  2. Кнопка переключается в неактивный режим, и появляется какой-либо спиннер, чтобы показать, что система работает.
  3. Запрос отправляется на сервер.
  4. Ответ от сервера отправляется обратно на страницу.
  5. Визуальное состояние кнопки и страницы обновляются в соответствии со статусом ответа.

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



Такой шаблон взаимодействия распространён повсеместно. Однако, одна проблема остаётся: пользователям по-прежнему нужно дожидаться ответа от сервера. Да, мы можем заставлять наши сервера работать быстрее, но как бы мы ни старались ускорить инфраструктуру, пользователям по-прежнему нужно ждать. А они этого, мягко говоря, не любят. Например, исследование показывает, что 78% потребителей ощущают негативные эмоции из-за медленных или ненадёжных сайтов. Более того, согласно опросу Harris Interactive для Tealeaf, 23% пользователей признаются, что проклинают свои мобильные устройства, 11% кричат на них, а целых 4% буквально швыряют их, столкнувшись с проблемами при совершении онлайн-транзакции. Временные задержки входят в число таких проблем.



Сегодня, даже когда во время ожидания вы показываете какой-то индикатор прогресса, если только вы не подошли к его созданию крайне оригинально, этого может быть попросту недостаточно. В целом люди привыкли к тому, что спиннеры свидетельствуют о медлительности системы. Они стали ассоциироваться с пассивным ожиданием, когда у пользователя нет другого выбора, кроме как ждать ответа сервера или полностью закрыть вкладку/приложение. Так что давайте попробуем еще улучшить это взаимодействие и посмотрим на концепцию оптимистичного UI.

Оптимистичный UI


Как уже было сказано, оптимистичный UI — не более чем способ обработки взаимодействия пользователя с интерфейсом. Чтобы понять его главные идеи, мы продолжим говорить о сценарии «пользователь нажимает на кнопку». Но принцип останется тем же для практически любого взаимодействия, которое вы захотите сделать “оптимистичным”. Как сообщает нам Oxford English Dictionary:

op-ti-mis-tic, adj. hopeful and confident about the future.

оптимистичный — полный надежд и уверенный в будущем

Давайте начнём с части про «уверенность в будущем».

Как вы думаете, как часто ли ваш сервер выдаёт ошибку в ответ на действие пользователя? Например, часто ли ваш API делает это при нажатии на кнопку? Или при клике по ссылку? Честно говоря, не думаю. Разумеется, это зависит от конкретного API, нагрузки на сервер, уровня обработки ошибок и других факторов, в которые вы как фронтенд-разработчик или UX-специалист можете совершенно не хотеть вникать. Но пока API стабильный и предсказуемый, а фронтенд корректно передаёт возможные действия с интерфейсом, количество ошибок в ответ на действия пользователя будет довольно низким. Я бы даже предположил, что оно не будет превышать 1-3%. Это значит, что в 97-99% случаев, когда пользователь нажимает кнопку на сайте, сервер ответит успешно и без ошибки. Это стоит проиллюстрировать:



Задумайтесь на секунду: если мы на 97-99% уверены в успехе определённого ответа, то мы можем быть уверены и в будущем — ну, по крайней мере, в куда большей степени, чем кот Шрёдингера был уверен в своём. Следовательно, мы можем изменить весь сценарий взаимодействия с кнопкой на следующий:

  1. Пользователь нажимает на кнопку.
  2. Визуальное отображение кнопки немедленно меняется на «успешное».

И всё! По крайней мере, с точки зрения пользователя, больше тут ничего нет — ни ожидания, ни необходимости наблюдать неактивную кнопку, ни ещё одного раздражающего спиннера. Взаимодействие пользователя с системой происходит гораздо более гладко, без напоминания системы о себе.



С точки зрения разработчика, полный цикл выглядит следующим образом:

  1. Пользователь нажимает на кнопку.
  2. Визуальное состояние кнопки немедленно меняется на успешное.
  3. Запрос отправляется на сервер.
  4. Ответ сервера отправляется обратно на страницу.
  5. В 97-99% случаев мы уже знаем, что он успешный, так что не требуется отвлекать пользователя.
  6. Только в случае ошибки система даёт о себе знать. Не волнуйтесь об этом сейчас — до ошибок мы ещё дойдём.

Давайте посмотрим на примеры такого оптимистичного взаимодействия. Вам, вероятно, знакомы кнопки «like» вроде тех, что есть в Facebook и Twitter.

Всё начинается, разумеется, с нажатия на кнопку. Но обратите внимание на её визуальное состояние после этого. Оно моментально отображается как успешное!



Давайте посмотрим, что в этот момент происходит на вкладке «Network» в Developer Tools нашего браузера.



Вкладка показывает, что запрос к серверу был отправлен, но всё ещё находится в процессе обработки. Счётчик «лайков» ещё не был увеличен, а сменой цвета интерфейс уже явно сообщает пользователю об успехе, ещё до получения ответа от сервера.

После успешного отклика счётчик обновляется, но этот переход куда менее заметный, чем немедленная смена цвета. В результате для пользователя всё проходит гораздо более гладко: никто не вмешивался, ничего не пришлось ждать.



Другой пример оптимистичного взаимодействия — Facebook с его кнопкой «like». Это довольно схожий с предыдущим сценарий, за исключением того, что Facebook обновляет счётчик сразу же, вместе со сменой цвета кнопки, не дожидаясь ответа сервера.



Кое-что тут следует отметить. Если мы посмотрим на время ответа сервера, обнаружим, что оно чуть больше 1 секунды. Это достаточно долго, учитывая, что модель RAIL рекомендует 100 миллисекунд в качестве оптимального времени отклика на простой запрос пользователя. Однако пользователь в этом случае не ощущает никакого времени ожидания из-за оптимистичной природы взаимодействия. Это ещё один пример психологической оптимизации производительности.

Но давайте признаем: по-прежнему остаётся вероятность в 1-3%, что сервер выдаст ошибку. Или пользователь попросту в офлайне. Или, что ещё вероятнее, сервер выдаст ответ, который технически является успешным, но содержит информацию, которую надо дополнительно обработать на клиенте. В результате пользователь не получит индикации ошибки, но мы не можем считать это и успехом. Чтобы понять, что делать в таких случаях, нам прежде всего нужно рассмотреть, какие психологические принципы лежат в основе оптимистичных UI.

Психология, стоящая за оптимистичным UI


Я пока ни разу не слышал, чтобы кто-нибудь жаловался на вышеупомянутые оптимистичные взаимодействия в популярных соцсетях. Поэтому предположим, что оптимистичные UI работают. Но почему они работают с точки зрения пользователей? Просто потому что люди ненавидят ждать. Вот и всё! Можно переходить к следующей части статьи.

Но если вы всё ещё читаете, вероятно, вы хотите узнать, почему все-таки это так. Давайте рассмотрим чуть глубже психологическое обоснование этого подхода.



Оптимистичный UI состоит из двух базовых компонентов, заслуживающих нашего внимания:

  • Быстрый отклик на действия пользователя.
  • Обработка потенциальных ошибок сервера, сети и так далее.

Быстрый отклик на действия пользователя


Говоря об оптимистичном подходе к UI, мы подразумеваем оптимальное время отклика во взаимодействии пользователя с системой. И рекомендации для такого взаимодействия существуют ещё с далёкого 1968-го. Тогда Роберт Миллер опубликовал свою фундаментальную работу «Response Time in Man-Computer Conversational Transactions» (PDF), где выделил целых 17 различных типов отклика, которые пользователь может получить от компьютера. Один из них Миллер назвал «ответом на активацию контроля» — задержку между нажатием клавиши и визуальным откликом. Ещё тогда, в 1968-м, оно не должно было превышать 0.1-0.2 секунды. Да, модель RAIL не первой это предложила — совету уже около 50 лет. Миллер отмечает, однако, что даже эта небольшая временная задержка может быть слишком медленной для опытных пользователей. Это означает, что в идеале пользователь должен получать подтверждение своего действия в течение 100 миллисекунд. Это близко к одному из самых быстрых бессознательных действий, которое способно совершить человеческое тело: к морганию. По этой причине 100-миллисекундный интервал обычно воспринимается как моментальный. «Большинство людей моргает около 15 раз в минуту, и каждое моргание длится в среднем 100-150 миллисекунд», говорит Дейвина Бристоу из Института неврологии в Университетском колледже Лондона, добавляя, что это «означает, что в целом мы тратим не меньше 9 дней в год на моргание».

Из-за моментального визуального отклика (происходящего до того, как получен ответ), оптимистичный UI — один из примеров техник раннего завершения, используемых в психологической оптимизации производительности. Но тот факт, что люди любят интерфейсы, отвечающие в мгновение ока, не должен удивить большинство из нас. И его не так уж сложно достичь. Даже раньше мы деактивировали кнопки моментально после нажатия на них, и этого обычно было достаточно, чтобы продемонстрировать «система знает о действии пользователя». Но неактивный элемент интерфейса означает пассивное ожидание: пользователь ничего не может с ним сделать и не контролирует процесс. А это очень раздражает пользователя. Вот почему в оптимистичном UI мы пропускаем всю «неактивную» стадию целиком — мы сообщаем о положительном результате вместо того, чтобы заставлять пользователя ждать.

Обработка потенциальных ошибок


Давайте перейдём ко второму интересному психологическому аспекту оптимистического UI — обработке потенциальных ошибок. Существует большое количество информации и статей о том, как лучше всего обрабатывать ошибки в интерфейсах. И хотя позже в статье мы рассмотрим и это, главное в оптимистичном UI — не то, как мы обрабатываем ошибки, а то, когда мы это делаем.

Дело в том, что людям свойственно разбивать свою деятельность на подзадачи, зачастую называемые «train of thought», «flow of thought» (PDF) или просто «flow». Это состояние «потока» характеризуется пиком удовольствия, энергетического фокуса и максимальной концентрации. Пользователь в «потоке» полностью погружён в свою деятельность. Твит Тэмми Эвертс хорошо иллюстрирует это:



В сети продолжительность таких периодов активности обычно гораздо короче. Давайте вернёмся к работе Роберта Миллера. В типах ответов, которые он перечисляет, есть такие:

  • Ответ списком информации на простой запрос
  • Ответ в графической форме на сложный запрос
  • Ответ на «Система, ты меня понимаешь?»

Все их он увязывает с одним и тем же 2-секундным интервалом, в течение которого пользователь должен получить соответствующий тип ответа. Не забираясь глубже, отметим, что этот интервал также зависит от рабочей памяти человека (промежуток времени, в течение которого человек может удерживать определённое количество информации в голове и, что важнее, производить действия с этой информацией). Для нас, разработчиков и UX-специалистов, это означает, что в течение 2 секунд после взаимодействия с элементом интерфейса пользователь будет в «потоке» и сосредоточен на ответе, которого ожидает. Если сервер выдаёт ошибку в течение этого промежутка времени, пользователь, можно сказать, всё ещё будет в «диалоге» с интерфейсом. Это похоже на диалог между двумя людьми, в котором вы говорите что-то, а другой человек мягко возражает вам. Представьте, если бы собеседник долгое время кивал в знак согласия (эквивалент успешного ответа в UI), а затем в итоге сказал «нет». Было бы странно, правда? Так что оптимистичный UI должен сообщать об ошибке пользователю в течение 2 секунд «потока».



Вооруженные психологическими знаниями об обработке ошибок в оптимистичном UI, давайте наконец доберёмся до этих 1-3% отказов.

Пессимистическая сторона оптимистичного подхода к UI


Самое распространённое заявление об оптимистичном UI, которое я слышал, заключается в том, что это антипаттерн — если угодно, обман пользователей. Вероятно, если подходить к вопросу сугубо формально, то так оно и есть. Тем не менее, я считаю это техникой предсказания или выражения надежды. (Помните определение слова «оптимистичный»? Вот мы и добрались до «полный надежд» в нём.) Разница между «обманом» и «выражением надежды» в том, как вы обходитесь с этими 1-3% ответов с ошибкой. Давайте посмотрим на то, как оптимистичная кнопка «like» у Twitter ведёт себя в офлайне.

Сначала, в соответствии с оптимистичным UI-паттерном, кнопка переключается на состояние успеха сразу после нажатия — опять же, без ожидания, в точности как если бы пользователь находился в онлайне.



Но поскольку пользователь в офлайне, запрос завершается неудачей.



Поэтому информация об ошибке должна быть донесена до пользователя настолько быстро, насколько возможно. Опять же, обычно для этого у нас не больше 2 секунд, пока пользователь находится в «потоке». Twitter сообщает об этом самым ненавязчивым способом из возможных — просто возвращая кнопку в первоначальное состояние.



Сознательный читатель тут может сказать, что при обработке ошибок можно зайти дальше, прямо уведомляя пользователя о том, что его запрос не мог быть отправлен или случилась ошибка. Это бы сделало систему максимально прозрачной. Но тут есть уловка — или, скорее, ряд сложностей:

  • Любое уведомление, неожиданно показанное на экране, меняет контекст задач пользователя, заставляя его анализировать причину отказа, скорее всего представленную в сообщении об ошибке.
  • Как и любое другое сообщение об ошибке или уведомление, это сообщение должно направлять пользователя в новом контексте, предоставляя ему информацию, на основании которой можно совершать действия.
  • Такая информация, в свою очередь, задаёт ещё один контекст.

Тут мы уже все можем согласиться, что ситуация становится слишком сложной. Несмотря на то, что такая обработка ошибок была бы уместной, например, для большой формы на сайте, для такого простого действия, как нажатие лайка, это слишком — как в отношении необходимой технической разработки, так и в отношении рабочей памяти пользователей.

Так что, да, в оптимистичном UI мы должны быть «прозрачны» в отношении ошибок и должны сообщать о них как можно скорее, чтобы наш оптимизм не превращался в обман. Но наши действия в таком случае должны соответствовать контексту. Для неудавшегося лайка простого возвращения кнопки в исходное состояние, скорее всего, будет достаточно — ну, конечно, кроме случая, когда вы лайкаете статус своей второй половины, тогда системе лучше бы работать всегда.

Экстремальный пессимизм


Может возникнуть такой вопрос: что произойдёт, если пользователь закроет вкладку браузера уже после отображения успеха, но до того, как запрос вернётся с сервера? Самым неприятным случаем было бы, если бы он закрыл её даже до того, как запрос отправился на сервер. Но если только пользователь не чрезвычайно ловкий или обладает способностью замедлять время, это вряд ли возможно.

Если оптимистичный UI используется правильно, и этот тип взаимодействия применяется только к тем элементам, которые никогда не ждут ответа сервера дольше 2 секунд, тогда пользователю потребовалось бы успеть закрыть вкладку в течение этих 2 секунд. Это не слишком сложно сделать нажатием клавиш; однако, как мы знаем, в 97-99% этих случаев запрос был бы успешным вне зависимости от того, открыта ли вкладка (ответ просто не был бы возвращён клиенту).

Так что проблема может возникнуть только для тех 1-3%, которые получили ошибку сервера. Как много людей спешат закрыть вкладку за 2 секунды? Если только они не участвуют в конкурсе по закрыванию вкладок на скорость, вряд ли их число будет значительным. Но если вы считаете, что это в вашем конкретном случае это может иметь значение и привести к негативным последствиям, тогда используйте инструменты для анализа пользовательского поведения; если вероятность такого сценария достаточно высока, то ограничьте оптимистичное взаимодействие исключительно не-критическими элементами.

Я намеренно не стал упоминать случаи, в которых ответ сервера искусственно задержан — это обычно не входит в область интересов оптимистичного UI. Теперь, когда мы потратили более чем достаточно времени на пессимистическую сторону вещей, давайте подведём небольшой итог, касающийся правильного использования оптимистичного UI.

Практические правила


Я искренне надеюсь, что эта статья помогла вам понять некоторые главные принципы, на которых основан оптимистичный подход к UI. Возможно, вам захочется попробовать его в своём следующем проекте. В таком случае, вот некоторые вещи, на которые стоит обратить внимание перед началом:

  • Прежде всего убедитесь, что ваш API надёжен и возвращает предсказуемые результаты. Это чрезвычайно важно.
  • Интерфейс должен находить потенциальные ошибки и проблемы до того, как запрос отправится на сервер. Ещё лучше — полностью избавиться от чего-либо, что может привести к ошибке с API. Золотое правило: чем проще UI-элемент, тем проще будет сделать его оптимистичным.
  • Применяйте оптимистичные паттерны только к простым «бинарным» элементам, от которых не ожидается ничего, кроме ответа об успехе или неудаче. Скажем, если кнопка предполагает варианты ответа сервера «да», «нет» и «может быть» (каждый из которых может означать успех в некоторой степени), то такую кнопку лучше оставить без оптимистичного паттерна.
  • Знайте время ответа своего API. Это критично. Если вы знаете, что для какого-то конкретного запроса время ответа никогда не оказывается ниже 2 секунд, то для начала займитесь работой над API. Как мы уже выяснили, оптимистичный UI работает лучше всего для времени ответа менее 2 секунд. Выход за эти пределы может привести к неожиданным результатам и большому количеству недовольных пользователей. Я предупредил.
  • Оптимистический UI — это не только про нажатия на кнопки. Этот подход может быть применён к различным событиям в жизненном цикле страницы, включая её загрузку. Например,skeleton screens следуют тому же принципу: вы надеетесь, что сервер ответит успешно, и заполнит плейсхолдеры, показываемые пользователю как можно раньше.



Как мы увидели, оптимистичный подход к UI не является ни каким-то новшеством, ни продвинутой техникой. Это просто ещё один способ, помогающий вам управлять восприятием производительности своего продукта. Базируясь на психологических аспектах, оптимистичный UI, при правильном применении, может помочь в создании позитивного и более сглаженного взаимодействия пользователя с вашей системой, требуя от вас при этом минимальных ресурсов. Но чтобы добиться от этой техники максимальной эффективности и не обманывать пользователей, нам необходимо понимать принципы ее работы.

Ссылки







Автор этой статьи (и её иллюстраций!) Денис Мишунов 11 декабря выступит в Москве на конференции HolyJS с кейноутом о том, как «запускать дебаггер» для себя самого. Летом на петербургской HolyJS он рассказывал о психологическом восприятии производительности, и тогда его выступление попало в топ-3 наиболее понравившихся зрителям — так что и в этот раз стоит ожидать, что будет интересно.
Tags:
Hubs:
+25
Comments 28
Comments Comments 28

Articles

Information

Website
jugru.org
Registered
Founded
Employees
51–100 employees
Location
Россия
Representative
Алексей Федоров