А помните ли вы свой первый мобильный телефон? Для меня это была Nokia 3310, неубиваемая «трубка», неустанно радовавшая меня скудным набором развлечений в виде игры в змейку, WAP и чудесных монофонических рингтонов. За последние тридцать лет индустрия шагнула далеко вперед. И это ещё мягко сказано: мобильные чипы приближаются по производительности к современным компьютерам, а две самые популярные на текущий момент системы — Android и iOS — предоставляют практически безграничные возможности для создания приложений на любой вкус.
Оплата по NFC, заказ такси буквально за пару свайпов, и даже тот же Instagram настолько плотно вошли в нашу жизнь, что необходимость создания мобильного клиента для своего бизнеса теперь уже не вызывает вопросов. Стандартом разработки в этом случае принято считать нативные приложения. Они работают плавно, имеют привычный пользователям UI и UX, а также доступ к разнообразным аппаратным возможностям смартфона и его операционной системы. Из основных недостатков этого подхода можно отметить необходимость иметь в штате выделенных iOS- и Android-разработчиков, возникновение сложностей в организации тестирования, и более длительный, по сравнению с web, релизный цикл. Нельзя забывать и про сегментацию: часть пользователей предпочитает оставаться на старых версиях приложения, старых версиях iOS и Android, обожают свои старые телефоны. Поэтому ненайденный в релизе баг, просочившись в сторы, напоминает землетрясение с долгим афтершоком.
Если у вас уже есть команда опытных мобильных разработчиков и налажен CI, то кажется, что выбор очевиден. Но зачастую бывают ситуации, когда время запуска функциональности в прод играет решающую роль, а постоянные обновления не идут на пользу репутации приложения. Хотя бы раз в жизни, каждый из нас брал кредит, или, по крайней мере, всерьез задумывался об этом. Обычно этот процесс включает в себя заполнение анкеты. Представим, что такая анкета есть у вас на сайте и в мобильном приложении. И вот банк решил освободить зарплатных клиентов от половины полей — это, безусловно, прекрасно, но влечет за собой изменения на сайте, а также в iOS- и Android-приложениях. Учитывая нашу асинхронность релизных циклов, а также возможность появления багов при обновлении, возникает риск получить три разные анкеты на неопределенный срок. А если подобные изменения нужно вносить часто?
Очевидное решение — гибрид. Существует множество фреймворков, позволяющих писать код сразу под обе платформы: Flutter, React Native, Ionic, однако их внедрение в существующий проект может стоить значительного времени и трудозатрат. Есть способ проще: помещая часть функциональности в WebView, мы можем быстро и относительно дешево переиспользовать часть уже реализованной на сайте логики. Контент, загружаемый из сети, в связке с нативными компонентами подчас абсолютно неотличим от нативного экрана. Так пользователи получат доступ к новым фичам одновременно с веб-версией, а мобильная команда сможет проработать полноценный нативный процесс в менее жестких временных рамках.
Если вы пошли по пути «гибрида», то важно понимать, когда это решение временное, а когда постоянное. Экран в WebView, как и любой другой, является частью экосистемы приложения. Запуская функциональность с объемной бизнес-логикой, придется закладывать значительное время и ресурсы на её поддержку. Но почему, если всё уже давно свёрстано и прекрасно работает?
50 оттенков сервисов
Тестирование под разные браузеры и разрешения — обычное дело при разработке фронта. Теперь этот чеклист пополнит ещё и мобильное приложение. Всё дело в WebKit-е, свободном движке для отображения веб-страниц, на котором работают все самые популярные браузеры. Он отвечает за единообразный разбор HTML, построение DOM, создание объектов window и document, работу с CSS, а также построение макетов и позиционирование UI-элементов. Однако при всём видимом удобстве, он насчитывает немалое количество версий, или, как их ещё называют, — «портов».
От одной версии к другой могут различаться подходы к управлению рендерингом, декодированию изображений и работе с видео; меняется поддержка кодеков, сетевой слой, а также используются разные JS-движки. Также WebKit позволяет включать или выключать любую функциональность на этапе компиляции при помощи compile-time feature flags, и даже в рантайме, при передаче параметров в командной строке или конфигурации. Прибавьте ко всему этому факторы, зависящие от «железа», и становится очевидно: браузер на телефоне точно будет отличаться от своего одноименного десктопного собрата.
Таким образом, встраивая в приложение «браузер на минималках» перед выкаткой в прод всё равно стоит закладывать дополнительное время на тестирование экрана, а лучше всего процесса.
WebView ≠ адаптив
Если пользователи привыкли менять вкладки при помощи свайпов, то на экране с WebView они будут ожидать поддержки такого же поведения. То же самое касается нативной навигации между экранами и UI-элементов (кнопок, полей ввода, контекстных меню и т.п.).
С точки зрения UX и дизайна, процесс работы с приложением должен оставаться согласованным, а руководящие принципы разработки пользовательских интерфейсов платформ должны быть учтены. Можете считать, что создание отдельной верстки под WebView это неизбежная плата за возможность мгновенного обновления функциональности без привязки к мобильным релизам. Чтобы поддержка функциональности в WebView не причиняла вам боль, с самого начала тратьте время на создание базы UI-компонентов со стилями, использованными в приложении.
Бесшовный процесс
UI приведен к общему виду, и даже самый нервный дизайнер опустил нож? Новый экран не зависит от других и не требует ввода данных? Тогда, пожалуй, можно пропустить этот пункт… Но лучше не торопитесь.
Важно учесть, что экран в WebView не должен уводить пользователя на другие страницы сайта. Многие приложения хранят личные данные клиентов, а следовательно, требуют аутентификации. И все, кто однажды вошел в свой личный кабинет, будут ожидать, что они останутся авторизованными и на экране в WebView. Используя механизм перехвата ссылок, вы можете направить пользователя в нативный процесс логина или регистрации, и таким образом избежать незапланированных ветвлений сценария в браузере.
На протяжении пользовательского пути зачастую возникает необходимость сохранить прогресс и полученную информацию. Открывая гибридный экран, не будет лишним передать в параметрах ссылки всё, что необходимо для продолжения работы. Что касается обмена данными в реальном времени, то его легко организовать, используя коллбэки. Например, с их помощью WebView может передать информацию о пунктах, которые должны отображаться в контекстном меню, а нативное меню, в свою очередь, вернёт пункт, на который нажал пользователь, и браузер загрузит нужную страницу.
Хотите встроить экран в существующий процесс? Без проблем. Но при этом логика работы приложения должна оставаться согласованной, а данные — консистентными. Библиотека WebKit в связке со средствами JS, реализованными интерфейсами на стороне Android и message handler со стороны iOS способны обеспечить глубокую интеграцию WebView-экрана и нативного кода. Вы сможете добавлять нативные виджеты поверх страниц, управлять их UI, добавлять требуемое поведение и настраивать видимость.
Тёмная сторона WebView
Начиная с Android 10 и iOS 13 появилась функциональность, называемая «тёмной темой». Это альтернативная цветовая схема UI, предназначенная для заботы о ваших глазах во время использования телефона в ночное время. Библиотека WebKit позволяет выставить настройки, согласно которым загруженная страница будет отображаться в соответствии с темой, установленной в текущий момент на телефоне (рекомендуемый режим), всегда в тёмном или светлом виде. Обратите внимание, что добавление поддержки тёмной темы в CSS веб-страницы строчкой @media (prefers-color-scheme: dark)
не даст нужного результата, так эта настройка влияет только на контролы — панель прокрутки, кнопки приближения и отдаления и т.д., но не на стиль контента, отображаемого внутри WebView.
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCEDARK)) {
WebSettingsCompat.setForceDark(WebSettingsCompat.FORCEDARK_AUTO)
}
Если в вашем приложении заданы стили для тёмной темы, это уже отлично, но и экран в WebView тогда обязан выглядеть соответствующе.
Разделяй и властвуй
Одними из важнейших показателей стабильности мобильных приложений являются доля crash-free users и отзывы в сторах. И если раньше все данные об ошибках, логи и пользовательские метрики можно было найти в Firebase или любом другом любимом вами сервисе, то теперь отладка и сбор аналитики станут несколько сложнее. В то же время оценки пользователей всё так же будут отражать их отношение к продукту целиком, вне зависимости от того, в какой части работы с гибридом у них возникли затруднения. Разбор каждого такого случая теперь будет начинаться с выявления источника: ошибка в нативе или вебе, или всё же в интеграции. Решением может стать сегментирование отзывов пользователей по тегам и перенос аналитики в единый кроссплатформенный сервис.
Один из популярных сервисов мониторинга активности приложений в App Store и Google Play — AppFollow. Он предоставляет автоматическую разметку отзывов пользователей. Для этого нужно прописать правила, согласно которым будут проставляться теги. Например, к жалобам на баги можно отнести отзывы с наличием в тексте слов «баг», «ошибка» или «не работает», а также с оценкой меньше 3.
А для сбора аналитики отлично подойдет ClickHouse — open source СУБД российской разработки, предназначенная для работы с большими объёмами данных. Она способна эффективно обрабатывать запросы в реальном времени, при этом их синтаксис максимально приближен к классическому SQL. Помимо быстродействия и низкого порога вхождения для пользователей стоит также отметить отлично реализованное сжатие данных и отсутствие проблем с подключением — у сервиса активное сообщество, на текущий момент есть готовые коннекторы под большинство популярных языков программирования. А если мне до сих пор не удалось вас убедить, то посмотрите руководство, знакомство с функциональностью займёт буквально пару часов, а тестовые данные идут в комплекте.
Подводя итог, становится понятно, что «быстро и относительно дёшево запуститься в WebView» — задача нетривиальная, если говорить о крупных и хорошо оттестированных фичах. Но зато этот подход отлично применим для кратковременного промо, раздела со справочной информацией, динамических форм обратной связи — иными словами, для экранов с часто изменяемой информацией, не завязанных на основные сценарии приложения.
Выбирая между запуском MVP в нативе и WebView, важно понимать, что лучшее решение принимается только в контексте задачи. Нативные SDK позволяют эффективно контролировать объём памяти, используемой приложением, загружать файлы в фоне, хранить локально большие объёмы данных, а также использовать все аппаратные преимущества современных смартфонов и систем iOS и Android. Требуется минимальный Time To Market? Гибридное решение позволяет запускать новую функциональность синхронно с сайтом, фиксить баги быстро и одновременно на всех устройствах. Однако при его некачественном исполнении пользовательский опыт может серьёзно пострадать.
Так где же золотая середина? WebView может неплохо себя показать в качестве заглушки, однако, как известно, нет ничего более постоянного, чем временное. Отличным вариантом будет начать разработку нативной версии одновременно со страницей гибрида. Мобильные разработчики смогут быстро погрузиться в контекст, фронты — корректно доработать вёрстку, пользователи получат фичу в самые короткие сроки, а через релиз экран уже станет нативным. Выбирайте мудро, используйте инструменты правильно, и результат не заставит себя долго ждать.
P.S.: А для тех, кому уже не терпится добавить в вёрстку своих приложений WebView, есть отличные новости. Следующая статья будет посвящена особенностям реализации, взаимодействию веб и нативных компонентов, а также тестированию гибридных экранов. Stay tuned!