6 февраля 2014 в 15:36

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

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

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

Правила организации высокоскоростного взаимодействия пользователя с приложением можно сформулировать следующим образом:

  1. Вычисления не должны блокировать взаимодействие с интерфейсом и его рендеринг — пользователь всегда должен иметь возможность указать на фокус своих интересов.
  2. Страница объекта, к которому обратился пользователь, должна отображаться мгновенно, не дожидаясь загрузки данных, в которых нуждается объект.
  3. Запросы в сеть не должны уходить одной большой группой, не должны отправляться сразу; должны откладываться на небольшое время, складываться и приоритезироваться в случае необходимости.


Изложенная в этой заметке информация — это мой практический опыт проектирования и разработки интерфейса моего приложения для поиска и прослушивания музыки seesu.me. Приложения, в котором гармонично комбинируются огромные пласты данных из разрозненных сервисов, таких как last.fm, вконтакте, ex.fm, hypem.com, soundcloud.com, discogs.com, youtube.com




Рекомендации, связанные с улучшением обратной связи без улучшений производительности, публиковались про работу приложения instagram. Но рекомендации не касались ни навигации, ни получения данных, а, скорее наоборот, — были связаны с отправкой.
speakerdeck.com/mikeyk/secrets-to-lightning-fast-mobile-design
image

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

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

Мгновенная обратная связь — это только один из нескольких базовых принципов, которых я придерживаюсь. Проектируя интерфейс своего приложения для прослушивания музыки, я руководствуюсь принципами и идеями, изложенными в книге Джефа Раскина «Интерфейс: новые направления в проектировании компьютерных систем». А также выводами и следствиями из его идей.

Джеф Ра́скин — специалист по компьютерным интерфейсам, автор статей по юзабилити и книги «The Humane Interface», сотрудник № 31 фирмы Apple Computer, наиболее известен как инициатор проекта Макинтош в конце 70-x.

Кратко основные используемые мной тезисы из книги я могу сформулировать так:

  • Представление информации должно быть реализовано в виде масштабируемой структуры;
  • Мгновенная обратная связь, выдача максимально возможной структурированной информации при минимуме введенных данных;
  • Только контекстное требование дополнительного ввода данных от пользователя. Только в момент непосредственной необходимости дополнительных данных.
  • Отказ от «интуитивности», «количества кликов», “количества нажатий” как мер эффективности интерфейса;
  • Формирование новых привычек пользователя;
  • Полный отказ от модальных окон.


Так, руководствуясь принципом мгновенной обратной связи из книги, опубликованной впервые в 2000 году, я запустил habrahabr.ru/post/88494 мгновенный поиск за пол года до того как google запустил instant search. en.wikipedia.org/wiki/Google_Search#Instant_Search

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

  1. Что бы не происходило в приложении, как бы оно не было занято вычислениями, пользователь всегда может указывать на то, что ему нужно. В приложении, написанном на джаваскрипте я использую setTimeout для разблокирования интерфейса (так же я планирую использовать setImmediate, и requestAnimationFrame — рендеринг не должен надолго блокировать возможность кликать и т.д.).
  2. Сразу, ещё до загрузки данных, наполняющих объект, отображается не просто страница объекта сама по себе, не пустой экран, но вся её структура. Отображаются её части, визуальные блоки, которые так или иначе зависят от данных, ещё не полученных из сети. Кроме этого отображаются и все блоки объектов, вложенных в этот объект. Когда приходят данные, отображаемые блоки наполняются. Это позволяет пользователю сразу анализировать структуру страницы и принимать решение о перемещении к другому объекту, не дожидаясь окончания загрузки.
  3. При перемещении от объекта к объекту пользователь четко даёт знать о фокусе своих интересов. В первую очередь должны быть выполнены запросы на получение данных для целевой страницы пользователя. Остальные запросы могут быть выполнены позже либо вообще отменены, например это такие как невыполненные запросы для страниц, которые покинул пользователь. Объекты могут быть вложены в другие объекты и иметь собственные запросы. Одни из запросов могут быть нужны для отображения данных в контексте пользовательского интереса, а другие — нет. Приоритеты таких запросов также следует изменять, причём в таком порядке, в котором данные используется на странице, и, соответственно, в том порядке, в котором объявлены представления вложенных объектов. (Т.е. страница, состоящая из множества элементов и вложенных объектов, будет пополнятся по мере поступления данных сверху вниз).


При переходе к странице артиста сразу же отображается вся структура страницы.



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



Чтобы полностью отобразить страницу артиста, соблюдая требование выдачи максимально возможной структурированной информации при минимуме введенных данных, в seesu выполняется 3 запроса в last.fm, 3 в hypem.com, 2 в discogs.com, 2 в soundcloud.com.



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

Вы можете сами зайти на seesu.me/o#/catalog/Pixelord/_ и попробовать быстро переключать разные композиции для того, чтобы убедиться, что данные для последней выбранной композиции будут загружены скорейшим образом. И только потом будут загружены данные для следующей композиции и некоторые данные для предыдущей.

Так же (в качестве эксперимента) можно попробовать открыть страницу списка списков композиций last.fm пользователя http://seesu.me/o#/users/lfm:yodapunk/tracks, где элементы загружаются сверху вниз. Выберите самый последний элемент из загруженных и убедитесь, что он загружен, после чего можно мгновенно вернуться вернуться назад, чтобы обнаружить, что выбранный вами список загружен вне очереди.






Комбинация трех этих подходов и относительно фиксированное расположение, высота и ширина визуальных блоков позволяют осуществлять комфортное и крайне быстрое перемещение внутри приложения, формирующееся в привычку. Ускорение рендеринга, вычислений и уменьшение времени получения ответа от сервера сделает приложение молниеносным, а ненавязчивая анимация переходов между страницами сгладит впечатление от задержки при выполнении сетевых запросов (в Seesu я использую анимацию длительностью в 120 мс).





О том, как я пришёл к этим правилам

(можно не читать)

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

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

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

У api сервиса last.fm нет ограничений на количество запросов, однако, при быстром перемещении от страницы к странице количество одновременно выполняемых запросов могло в ряде случаев более 6 (шести). Ни один браузер не открывает больше 6 соединений к одному домену. При большом количестве запросов становится заметна нагрузка на него. Я обратил внимание на то, что пользователь может передумать и переместиться на другую страницу до того, как будут получены данные по запросу. Это наблюдение делает очевидным тот факт, что мгновенная отправка запросов не сокращает ожидание получения пользователем нужной информации, а, наоборот, увеличивает. Поняв это, я принял решение разряжать и приотизировать все сетевые запросы.

Приоритезация запросов на первоначальном этапе была реализована исключительно для страниц со списком композиций. В дальнейшем, когда я стал гораздо активнее использовать last.fm api, подключая новые источники данных, я реализовал приоритезацию и разрядку запросов для всех страниц, для всех api. Сейчас при переходе от страницы к странице, при добавлении нового запроса в существующую очередь, приоритеты автоматически пересчитываются, меняются, учитывая текущую страницу и запросы, необходимые ей. Остальные запросы выполняются (не завершаются) в обратном порядке добавления.

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

Приходилось ли вам слышать?
— «БУДЕТ БОЛЬШАЯ НАГРУЗКА НА СЕРВЕР!»

С помощью отложенной отправки, разрядки запросов и мгновенной обратной связи в сентябре 2010 года мы с rossomachin сделали самую крутую форму проверки доменов shop.masterhost.ru/templates/default/domains. Несмотря на технические ограничения и ограниченную реализацию наших пожеланий со стороны серверных разработчиков.



О будущем разработки интерфейсов

(можно не читать)

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

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





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

Последовательное и планомерное соблюдение принципа мгновенной обратной связи при реализации в сису требовало от меня дополнительного программирования, времени по проектированию дополнительных состояний интерфейса.

В моем случае все страницы приложения должны быть спроектированы с возможностью отображения их без загруженных данных; с учетом того, что страница должна наполняться, перерисовываться по мере поступления данных. Такое требование с точки зрения технической реализации должно было быть сделано без нагрузки на браузер — с помощью атомарных изменений DOM. Либо с помощью перерисовки огромных визуальных блоков, что вызывало бы нагрузку на браузер. Загруженный браузер лишает пользователя возможности быстрого взаимодействия. На реализацию частичной перерисовки отображения должно быть потрачено время сначала ручным, полуавтоматическим способом для каждой страницы. Позже это время сведётся к минимальному после того, как будет потрачено время на создание системы для автоматических перерисовок. Должна была быть реализована приоритезация запросов с учётом взаимосвязей, потому что запросов много и они образуют неуправляемые, нагружающие браузер очереди.

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

Что бы организовать код, отвечающий сложным требованиям и не сойти сума, занимаясь в одиночку приложением с огромными пластами данных, я использую самописный фрейворк и шаблонизатор. Код описывает сложные взаимосвязи объектов, взаимосвязи их состояний, структуру страниц; отвечает требованиям отображения данных в масштабируемой структуре, приоритезации объектов, удобной шаблонизации, принципу разделения на MVC. Я уверен, что справлюсь с построением любого нового интерфейса, отвечающего всем перечисленным требования, используя в связке собственные инструменты гораздо эффективней, чем используя другие существующие на рынке инструменты. Эффективность моих инструментов можно улучшить, но даже после улучшений ничего из этого не сможет стать инструментом делающим доступной возможность построение современных интерфейсов для широких слоев разработчиков. Также как и другие библиотеки не являются таким инструментом. При этом для меня очевидно, что существование таких инструментов возможно.
Глеб Арестов @arestov
карма
39,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (27)

  • +4
    А теперь, пожалуйста, от слов – к делу!

    Как мне это всё сделать?

    Подкиньте технической информации в топку топик. Как, например, приоритезировать ajax-запросы в javascript (это вообще возможно)? Опубликуйте свои инструменты – все посмотрят и начнут их использовать, доработают или переработают.
    • +7
      Статья, я думая, достигла цели «указать на проблему», и даже «указать в сторону решений проблемы». Это уже много.
      Разве ссылок + view source не достаточно, для умного человека? Хаять легко — уверен, что при видимом интересе несколько человек опишут технические моменты. IT — это широкая, быстроизменяющаяся, сфера, и нет смысла описывать все know-how, если они не нужны.
      Принципы и подходы показаны. А что, конкретно, сделать — это слишком широкий вопрос (Честно честно).

      Не факт, что это направление, реально кому-то интересно. А трудоёмкость создания подобных вещей раза в 3 выше, чем при традиционных подходах.
      У меня к примеру, внутренняя дока, по куску, который описывает принципы построения domain model, для dirty read занимает 50 килобайт (это не статья, а выжимка).
  • +2
    Отличная статья. Я сам испытываю большое раздражение видя индикатор загрузки, когда ожидаются совсем не то, что мне нужно именно в этот момент.
    Полтора года назад, когда я только начал, пересмотрел все доступные (на тот момент) фреймворки. К сожалению, самое близкое, что было найдено — google closure library.
    Толстая модель с чтением грязных данных, ленивая загрузка с кэшированием, использование объектной модели контролов вместо шаблонов, нотификации, ивенты, предугадывание поведение пользователя…
    При доведении цели SUBJ к абсолюту приходится использовать совершенно другие patterns, чем при обычном подходе.

    Автор на столько скромен, что самое интересное написал в разделе с пометкой «можно не читать» ;)
  • +1
    Несмотря на то что по скорости работы претензий к seesu.me не возникало, дизайн у сайта крайне неудобный и непонятный, можно сказать худший из всех плееров которыми я пользовался.
    Ну и соответственно дико видеть какие-то советы по дизайну от автора этого сайта…
    • +2
      Он не подходит под ваши сценарии/привычки — и только. А мне, например, подошёл лучше обычных винампообразных плееров.
    • +1
      советы не про абстрактный дизайн, а про создание интерфейсов с которыми можно быстро взаимодействовать — о том, к чему у вас претензий нет ;)

      интересно было бы узнать почему идеи Джефа Раскина не позволяют создавать удобные унтерфейсы, или в чем приложение противоречит его идеям
      • +1
        В том-то и дело что в результате оптимизации работы интерфейса им стало неудобно пользоваться. И в посте есть и про дизайн, просто в тесной сцепке с производительностью, например:
        «Комбинация трех этих подходов и относительно фиксированное расположение, высота и ширина визуальных блоков позволяют осуществлять комфортное и крайне быстрое перемещение внутри приложения, формирующееся в привычку.»

        Хотя я наверно ошибся с термином, точнее будет сказать не дизайн, а интерфейс — взаимодействие с пользователем.
        • –1
          а в чем собственно неудобство?
          • +1
            Очень непонятный механизм управления — практически на каждом шагу приходится некоторое время искать и думать что же тут надо/можно нажать чтобы получить результат.
            Я не дизайнер и не могу сказать какие конкретно элементы интерфейса создают такой эффект, но как вы видите из других комментариев, так сайт воспринимаю не только я.

            Могу только привести примеры — хочу послушать музыку 90х, выбираю «90х» и сразу затык — куда дальше? После раздумий — нажимаю «Композиции/лучшее» — и опять неясно куда дальше нажать… После раздумий и экспериментов оказывается что нужно опять нажать «лучшее», после чего появляется список песен и не играет — нужно самому ткнуть на любую композицию.
            Ну и конечно кнопка «Следующий» при проигрывании трека отлично «заметна и понятна» для новичка.
  • +1
    «какие-то советы по дизайну от автора» автор вроде бы и не давал по дизайну советов, он рассказал о своих наработках в технологии быстрого взаимодействия с интерфейсом.
    Интерфейс НЕ дизайн.
    Хотя я тоже ничего не понял, куда нажимать сразу. Но обсуждение дизайна выходит за рамки статьи.
  • –3
    это комментарий ненависти заколебавшегося пользователя интернета.

    Честно говоря, ненавижу сайты, которые загружаются моментально, но без контента. Вместо него крутится индикатор загрузки, и зачастую крутится неприемлимо долго, так что я всё равно ухожу с сайта. Кроме того у меня отключен яваскрипт в целях безопасности, и такими сайтами просто невозможно пользоваться. Мне наплевать на 100500 рюшечек, виджетов, кнопочек; я пришел на сайт за нужной мне информацией (которая чаще всего текстовая). Отдельно посылаю лучи ненависти платформе gawker.
    • +1
      Вы описали ситуацию под названием «Плохо» с картинки
      habr.habrastorage.org/post_images/44e/74a/813/44e74a813a70bdc1da54885d31d26100.png
      интерфейсы, сделанные подобным образом, действительно вызывают крайне неприятные ощущения.

      В статье я рассказываю как сделать хорошо
      • 0
        Да, я это понял. Я рад что ещё есть люди у которых голова используется не только для приема пищи. Но к сожалению иногда сложно провести черту между плохо и хорошо. Тот же T-Mobile загружает навигацию и структуру быстро, а данные счета (то зачем я вообще пришел) не загружает вообще (там какая то 500 ошибка в логах). Для обычного же юзера это выглядит будто страница загрузилась, всё работает, и нужные данные вот-вот будут, но он не понятия не имеет, что сервер чихнул и их не будет никогда.
  • –2
    Эту статью стоит прочитать только из-за экспертов, ее комментирующих :)
    Если интересует конкретика, то был доклад на UX'2010 на тему того, что быстро, а что медленно в интерфейсах
    webo.in/articles/ux2010/usability-time/
  • 0
    Этот подход отлично работает с юзерами на медленном канале. Если канал большой, то почти моментально загружающиеся и «прыгающие» блоки (на seesu в том числе) очень раздражают. Хочется воскликнуть «Ну загрузись уже что ли в конце концов и покажи через секунду красивую страничку без уродливых пустых блоков!».
    Вряд ли это только мой взгляд. Возможно, конечно, что дело в плохом дизайне seesu.
    • +1
      «Этот подход отлично работает с юзерами на медленном канале»
      Этот подход отлично работает с юзерами на медленном канале, с юзерами сервисов с медленными серверами, с юзерами сервисов использующих api других сервисов, у которых есть throttling. Этот подход превосходно работает с быстрыми серверами, мгновенно выполняющими запросы так, что страница наполняется данными прямо во время короткой анимации переходов между экранами. (можно поправить css в сису, увеличив время, и увидеть, что именно так всё и происходит))

      "«прыгающие» блоки (на seesu в том числе) очень раздражают"
      В seesu нет прыгающих блоков — "… фиксированное расположение, высота и ширина визуальных блоков ..."

      «Если канал большой, то почти моментально загружающиеся… »
      Возможно вы просто пропустили вторую часть, но я там пишу про то, что вконтакте, например, запрещает присылать больше одного запроса в секунду, discogs запрещает загружать больше одной картинки в секунду. Чтобы отобразить полностью страницу нужно отправить больше одного запроса.

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

      «Ну загрузись уже что ли в конце концов и покажи через секунду красивую страничку без уродливых пустых блоков!»
      Очевидно, что большой канал вас всё-таки не спасает.
      Смысл подхода в том, что не нужно ждать пока выполнятся все запросы, наполняющие страницу — можно мгновенно перейти на другую страницу. После перехода данные для выбранной страницы будут загружены в первую очередь.
      • 0
        Посыпаю голову пеплом, вы правы, я не прав. Я вспомнил, что меня дико раздражает в интерфейсе: попробуйте зайти на любую страницу неанглоязычного музыканта из-под хрома с включенным автоматическим переводом этого языка (в данном случае финского) — гугл пытается перевести названия песен и этим дико бесит.
        Можете вставить волшебный мета-тег в head?
        • +1
          ого, не знал про такой, обязательно добавлю. спасибо!
  • 0
    Для первого посещения страницы время для отображения информации, видимой на первом экране стало больше или меньше?
    Мне кажется больше. Ведь вместо 1 запроса, уже будет оправлен сразу 1, а потом еще несколько. Больше всего это будет заметно на мобильном интернете.
    • 0
      Не понял о чем точно идет речь. Какие действия произвёл пользователь, как перемещался по страницам и какие запросы в каком порядке в этом предполагаемом случае отправлены?
      • 0
        Речь о первом посещение сайта. По описанной схеме: сразу идет запрос на получение самой страницы, после её получения — запросы на получение данных. Так будет дольше, чем если загрузить все сразу.
        • 0
          Если вы говорите о случае, когда вы загружаете структуру (шаблон) страницы отдельно, каждый раз заново, и всё это в приложении где вся логика интерфейса находится на клиентской стороне, то их можно загружать параллельно с данными. Но этом вообще речи не идёт.

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

          Посмотрите сами seesu.me/o, можете попробовать засечь время за которое отображается структура страницы без данных :)
  • 0
    Чисто технически сайт seesu.me выполнен на высшем уровне, но похоже из Раскина вы почерпнули только технический аспект работы программ, большая часть идей книги «Интерфейс» осталась явно за бортом.
    • 0
      О каких конкретно, оставшихся за бортом, идеях идет речь?
      • 0
        Режимы в интерфейсе. Отключите звук в колонках, потом представьте что вы забыли как пользоваться вашим сайтом и попробуйте догадаться будет ли играть звук если нажать на круглую кнопку с треугольником. Т.е. один элемент управления делает 2 абсолютно противоположных действия, причем невозможно чисто по внешним признакам определить что именно он будет делать если его активировать.
        • 0
          Кнопка воспроизведения, с режимом (а ещё с индикатором и устройством выключателя света), которая не обязана своим видом помогать что будет происходить (нет я не строил интуитивно понятный интерфейс — Раскин против) и есть оставшаяся за бортом большая часть идей? Серьёзно?
          • 0
            Нет. Я пошутил. Догадаться о том, играет ли музыка можно только по анимации эквалайзера, сама кнопка не несет полезной информации. Совсем. Если вы думаете иначе — это заблуждение, но слава богу я не смогу вам ничего доказать потому что я всего лишь некомпетентный почти анонимус с хабра.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.