В недавнем сообщении в блоге я объяснил, почему команда инженеров Instawork переместила нашу веб-разработку с популярной архитектуры SPA + API на веб-страницы, отображаемые на стороне сервера. Рендеринг на стороне сервера позволяет нам быстро разрабатывать новые функции, используя единый язык (Python) и единую интегрированную структуру (Django). Добавление Intercooler.js дает нам интерактивность, подобную SPA, при сохранении всей бизнес-логики и рендеринга HTML на сервере.

Уровень производительности, которого мы смогли достичь с помощью Django + Intercooler, был невероятным, но влияние было относительно небольшим. Это потому, что основная платформа Instawork - не Интернет, а мобильная. Подавляющее большинство наших пользователей получают доступ к Instawork через собственные приложения для iOS и Android. А на мобильных устройствах мы все еще использовали ту же архитектуру, от которой только что отказались от Интернета: толстый клиент (написанный на React Native), извлекающий данные через JSON API.

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

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

  • Толстому клиенту необходимо знать возможные конечные точки API и формат JSON этих конечных точек, что приводит к дублированию кода.
  • Толстый клиент содержит логику, определяющую, как проверять вводимые пользователем данные и какие вводимые данные запрашивать. Серверу также необходимо выполнить эту проверку, что приведет к большему дублированию кода.
  • Толстый клиент содержит условную логику для определения того, как отображать данные API и как перемещаться между экранами на основе действий пользователя или ответов серверной части. Эта критическая логика существует исключительно во внешнем интерфейсе.

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

Когда мы поняли, что сетевые приложения плохо подходят для толстых клиентов, мы начали искать платформу для мобильных устройств тонкого клиента. Лучшим решением были веб-приложения HTML + JS, объединенные во встроенной оболочке (например, Cordova). Мы обнаружили, что это решение немного неуклюже для наших нужд: HTML не был разработан с учетом мобильных пользовательских интерфейсов, что привело к низкой производительности и неидеальному UX.

Мы не нашли существующей инфраструктуры тонких клиентов для нативных мобильных приложений. Итак, мы построили свой собственный.

Instawork рада анонсировать Hyperview, нашу платформу с открытым исходным кодом для разработки мобильных приложений с использованием той же архитектуры тонких клиентов, что и в Интернете. Hyperview состоит из двух частей:

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

Клиент Hyperview: мобильная библиотека (поверх React Native), которая может отображать HXML. Клиент может отображать любой экран HXML и обрабатывать навигацию и взаимодействие, отправляя дополнительные запросы HXML.

В Интернете страницы отображаются в браузере путем извлечения HTML.

С Hyperview экраны отображаются в вашем мобильном приложении путем получения Hyperview XML (HXML).

HXML

В HXML экраны мобильных приложений определяются в формате XML с использованием основного набора атрибутов и тегов. Опыт написания HXML должен показаться знакомым каждому, кто работал с HTML:

<doc xmlns="https://hyperview.org/hyperview">
  <screen>
    <body>
      <text>Hello, Hyperview!</text>
    </body>
  </screen>
</doc>

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

Собственный синтаксис для распространенных мобильных элементов пользовательского интерфейса

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

<section-list>
  <section>
    <section-title><text>Section 1</text></section-title>
    <item key="1"><text>Item 1</text></item>
    <item key="2"><text>Item 2</text></item>
  </section>
  <section>
    <section-title><text>Section 2</text></section-title>
    <item key="3"><text>Item 3</text></item>
    <item key="4"><text>Item 4</text></item>
  </section>
</section-list>

Пользовательский стиль ввода

Элементы ввода HXML позволяют полностью контролировать стиль для создания более настраиваемых форм. В HTML элементы ввода ограничены определенным внешним видом и семантикой, например радио или флажок. В HXML гибкие элементы, такие как <select-multiple> и <option>, могут отображаться в виде флажков, тегов, изображений или любой другой подходящей визуальной обработки.

Богатые взаимодействия без сценариев

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

<a href="/next-page">Behold, the power of the hyperlink!</a>

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

В HXML синтаксис поведения может выражать большой класс пользовательских взаимодействий с декларативной разметкой.

  • trigger позволяет выполнять действия не только при нажатии, но и при многих других типах взаимодействия с пользователем, например, при обновлении по запросу.
  • action позволяет поведению переходить на новый экран. Но он также поддерживает изменение текущего экрана путем замены, добавления или добавления содержимого HXML к элементам. action дает разработчикам возможности AJAX без необходимости писать обратные вызовы или обещания в коде.
  • Декларативные состояния загрузки могут скрывать или показывать части экрана во время выполнения запросов.

Возьмем этот пример фрагмента HXML:

<body id="Body">
  <list>
    <behavior
      trigger="refresh"
      href="/news"
      action="replace"
      target="Body"
    />
    <item key="1" href="/news/1">
      <behavior
        trigger="press"
        action="push"
        href="/news/1"
      />      
      <behavior
        trigger="longPress"
        action="new"
        href="/news/1/settings"
      />
      <text>Story 1</text>
    </item>
  </list>
</body>

Пример содержит три <behavior>elements, которые объявляют (соответственно):

  • Когда пользователь выполняет жест "потяните для обновления" в списке, отправьте HTTP-запрос на выборку /news и замените элемент с идентификатором Body содержимым ответа HXML.
  • Когда пользователь нажимает элемент, отправляйте HTTP-запрос на выборку /news/1 и показывайте содержимое на новом экране, помещенном в стек.
  • Когда пользователь долго нажимает на элемент, отправьте HTTP-запрос на выборку /news/1/settings и отобразите содержимое в новом модальном окне над текущим стеком.

С помощью HXML можно создать богатый мобильный пользовательский интерфейс на чистом XML без необходимости написания сценариев на стороне клиента. Фактически, HXML даже не поддерживает сценарии, что означает, что все состояние и бизнес-логика остаются в одном месте на сервере.

Клиент Hyperview

Клиентская библиотека Hyperview предоставляет компонент React Native Hyperview, который можно добавить в навигацию существующего приложения React Native. Самый важный параметр, переданный в Hyperviewcomponent, - это entrypointUrl. Когда компонент монтируется, он сделает запрос к URL-адресу точки входа, ожидая в ответе HXML. Как только клиент получает ответ, HXML отображается на текущем экране. Поведение в HXML приведет к навигации или обновлению текущего экрана. Клиент обрабатывает это поведение, выполняя последующие запросы новых битов HXML, и цикл может продолжаться бесконечно.

Другими словами, думайте о клиенте Hyperview как о веб-браузере, но для HXML. URL-адрес точки входа похож на жестко запрограммированный адрес на панели инструментов, указывающий на вашу домашнюю страницу. Домашняя страница содержит ссылки и формы, которые приводят к большему количеству запросов на дополнительный HXML. Истинная сила тонкого клиента становится очевидной, когда вы понимаете, что с помощью единого URL-адреса точки входа и макетов, управляемых сервером, есть бесконечные возможности для добавления и изменения экранов и взаимодействий в вашем мобильном приложении.

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

Hyperview в производстве

За последние 6 месяцев Instawork использовал Hyperview в своих мобильных приложениях для реализации десятков экранов. Опыт оказался фантастическим, и мы вдвое увеличиваем использование Hyperview в большинстве наших основных потоков приложений. Вот лишь некоторые из уже известных нам преимуществ:

Сосредоточьтесь на функциях, а не на архитектуре

В архитектуре толстого клиента / JSON API разработчикам необходимо принимать множество архитектурных решений при создании функции:

  • Как сохранить данные для моей функции?
  • Могу ли я расширить существующую конечную точку и ресурс API или создать новую?
  • Как смоделировать взаимодействие пользователя как HTTP-запросы?
  • Повлияет ли мое изменение на производительность других клиентов, использующих тот же API?
  • Достаточно ли общий дизайн моего API, чтобы обслуживать варианты использования, выходящие за рамки текущей функции, которую я создаю?
  • Не раскрываю ли я слишком много данных, чтобы сделать дизайн универсальным?
  • Совместимы ли мои изменения API со старыми версиями клиентов?
  • Как выглядит пользовательский интерфейс?

С Hyperview архитектурные решения, связанные с API, исчезают, и разработчик может сосредоточиться на важных частях функции:

  • Как сохранить данные для моей функции?
  • Как смоделировать взаимодействие пользователя как HTTP-запросы?
  • Как выглядит пользовательский интерфейс?

Лучшая производительность

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

Мгновенные обновления

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

Единый опыт для всех наших пользователей

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

Начни сегодня

Hyperview - действительно лучший способ разработки сетевых приложений для мобильных устройств. Исходя из нашего опыта в Instawork, требуется некоторое время, чтобы приспособиться к парадигме тонких клиентов при работе с мобильными приложениями, но как только вы к ней привыкнете, вы уже не захотите возвращаться. Начать работу можно разными способами:

  • Если вы хотите изучить Hyperview, прочитав пример кода, перейдите в раздел Примеры.
  • Чтобы получить полное представление об элементах и ​​поведении, доступных в Hyperview, ознакомьтесь с полным Справочником по HXML.
  • Если вы работаете в Интернете или в HTML, вы можете начать с нашего руководства, в котором освещаются некоторые различия между HTML и HXML.
  • Или, чтобы запустить демонстрацию самостоятельно, ознакомьтесь с нашим руководством Начало работы на следующей странице!

В будущих публикациях в блогах мы более подробно рассмотрим конкретные функции, бэкэнд-технологии и подробно обсудим дизайнерские решения, принятые при разработке Hyperview. Если вы попробуете, дайте нам знать, как это работает для вас!