Мало кто сможет удержаться от желания работать меньше, а получать больше. Это желание, исполненное в позитивном ключе, ведет к прогрессу, — пишет сайт DOU.UA. Одной из попыток достичь этого стала кроссплатформенная разработка мобильных приложений.
С ростом популярности смартфонов, планшетов, электронных книг и нетбуков мобильные платформы становятся все более актуальными — начиная от адаптивной верстки сайта и заканчивая полноценным приложением.
Давайте посмотрим, какие варианты кроссплатформенной разработки существуют и что они предлагают нам как создателям. Бизнес постучит со своими «хотелками», а выбор того, на чем писать, часто приходится делать именно разработчику.
В конце статьи вы найдете описание конкурса, победители которого смогут пройти курс изучения одного из перечисленных ниже фреймворков.
Проблема архитектуры в кроссплатформах
В мире кроссплатформы все фреймворки примерно одинаковы по своей структуре. В основе всего — целевая платформа (iOS, Android, etc.), для которой ведется разработка, и слой абстракции, который обещают сделать быстро, дешево и красиво, а между ними мост, соединяющий эти две сущности. Слой абстракции в большинстве своем представлен связкой из JS и CSS (частично или полностью).
У такой архитектуры есть типичные проблемы.
Частично они обусловлены тем, что слой абстракции, условно говоря, пытается усидеть на двух стульях — с переменным успехом. Отсюда и сложности: на каждой отдельно взятой платформе приложение отображается и ведет себя по-разному. Иногда это не проблема, но бывают случаи, когда уникальный дизайн и поведение на обеих платформах являются дополнительным business value.
В пример можно привести приложение Reflectly. Изначально оно было написано на React Native, впервые вышло на iOS, а позже была попытка выйти на платформу Android.
Запуск приложения в Android преподнес неприятный сюрприз. В итоге его полностью переписали на Flutter.
В данном случае приложение реализует уникальный функционал, уходящий немного в сторону от списков и форм, дизайн тоже является уникальным. Узнать подробности этой истории можно здесь.
Асинхронность и производительность моста, соединяющего две платформы. Все, что вы хотите от платформы (рендеринг, вызов нативных методов), вам сначала нужно сериализовать в строку, передать, по ту сторону десериализовать и только потом получить ожидаемый результат. Такие действия явно не увеличат производительность.
Работоспособность и поддержка плагинов. Кроссплатформа не так распространена, как классический фронтенд. Нередко плагин выпускается в Open Source, и практически сразу прекращается его поддержка, так как существующая версия решает проблемы разработчика, а за большее никто не будет платить. Еще хуже, когда прекращается не только поддержка, но и реагирование на pull requests…
Миф о том, что любого web-разработчика можно быстро переквалифицировать в мобильщика с помощью «магического фреймворка Х». Все выглядит похоже: на Web — CSS + JS, на кроссплатформе — то же самое. Должно работать. Но не учитывается факт, что к имеющимся знаниям требуется быстро прибавить понимание как минимум двух платформ (iOS и Android), с которыми разработчик раньше не сталкивался. Отдельным бонусом идет набивка руки в специфических тонкостях, связанных со взаимодействиями внутри всего этого зоопарка.
Из-за всех этих нюансов кроссплатформенную разработку троллят вот так:
Начнем знакомство с фреймворков, основанных на WebView.
Cordova
Одним из первых кроссплатформенных фреймворков стал Cordova (бывш. PhoneGap). Первый релиз состоялся в 2009 году. Изначально разрабатывался компанией Nitobi, купленной Adobe. В результате поглощения исходный код PhoneGap был передан Apache Foundation.
Из официальной архитектурной схемы видно, что основой рендеринга выступает обычный WebView — то есть обычный браузер. Несмотря на то что это самый давний фреймворк, предлагает он лишь джентльменский набор из плагинов и связки API для обеспечения их взаимодействия. Какого-то специфического набора инструментов у него нет. Есть перечень сервисов и библиотек, который предлагается на главной странице, например Onsen UI — UI-библиотека.
Developer experience довольно неоднозначный: фактически, как ты его себе организуешь, так и будет. Можно на jQuery все писать и обновлять страницу с F5, а можно собрать себе уютный и привычный набор библиотек и пользоваться уже существующими решениями для hot reload.
Дебаг происходит в консоли браузера. Дебаг на устройстве — через подключение из Safari к WebView, запущенном на iOS.
Также есть удобный механизм темплейтов, который позволяет генерить проект из готовых сторонних бойлерплейтов. Например, cordova-template-framework7-vue-webpack.
Ionic
На основе Cordova в 2013 году был выпущен Ionic. Со временем Cordova заменили Capacitor с сохранением совместимости API, чтобы осталась работоспособной вся существующая база компонентов.
Имеет свою базу UI-компонентов и позволяет реализовывать бизнес-логику на любом фреймворке из могучей тройки (до версии 4 была возможность использовать только Angular). Есть возможность оплатить энтерпрайз-поддержку. В остальном все сказанное о Cordova относится и к Ionic. Дебаг в консоли браузера, хот-релоад от фреймворка, работает внутри WebView.
Следующими рассмотрим фреймворки semi-native, которые предлагают писать на смеси CSS + JS (React Native, NativeScript, Appcelerator) или .NET (Xamarin), а на выходе получать приложение, практически не отличимое от нативного.
Appcelerator наименее известен (0 упоминаний в вакансиях на DOU), использует свой собственный фреймворк Alloy. Существует также версия с поддержкой Angular, но она все еще в бете, а движение в репозитории остановилось в 2108 году… Знать о нем можно, а изучать практического смысла нет 🙂
Xamarin
Фреймворк с длинной историей. Изначально развивался отдельно, позже был приобретен компанией «Майкрософт». Поскольку он «не на JS», то не очень популярен.
В отличие от JS-фреймворков код на C# компилируется, и это позволяет ему работать чуть быстрее. Также у него есть два варианта архитектуры.
Здесь UI-слой разрабатывается отдельно для обеих платформ, а бизнес-логика общая. Этот вариант будет интересен, если есть желание сделать максимально нативное приложение с точки зрения UI (с учетом всех гайдлайнов), а на дублировании бизнес-логики сэкономить путем повторного использования существующих наработок. В то же время требует наличия в команде разработчиков, способных написать UI-часть для обеих платформ отдельно.
Продолжение развития Xamarin, но уже с покрытием UI, не требующим написания по отдельности.
Доступны наборы инструментов для разработки на любой вкус. Есть бесплатная Visual Studio Community Edition и платная версия Visual Studio Professional по подписке за 45 $ в месяц.
Дебагер, хот-релоад (только для верстки), лейаут-эдитор — все имеется в наличии. Однако язык разработки и относительная дороговизна инструментов разработки делает Xamarin малораспространенным за пределами экосистемы Microsoft.
NativeScript
Фреймворк выпущен в 2014 году. На данный момент из коробки предлагается писать на Angular или Vue. За долгие годы развития накопил достаточно большой арсенал инструментов разработчика: готовый набор UI-компонентов, собственную песочницу, маркетплейс компонентов, приложение для быстрого запуска превью написанного кода на устройстве, приложение, где можно увидеть вживую работу компонентов. Для дебага можно использовать или консоль браузера, или предоставляемый разработчиками плагин для VS Code.
Имеет интересную архитектуру — API платформы через рефлексию пробрасываются на сторону JavaScript.
На практике работа с API-платформы выглядит так, как будто вы пишете, например, на Java, только через призму JS. В повседневной же работе используется набор встроенных layout-компонентов и CSS-подобный синтаксис для раскраски. При изменении стилей достаточно неплохо работает hot reload.
На выходе имеем бандл JS-кода, выполненный в JSCore (iOS) или V8 (Android) и работающий через мост с платформой.
React Native
Первый релиз состоялся в 2015 году. Практически единственный из кроссплатформенных фреймворков JS, который не дает нам выбора и предлагает только React как фреймворк для разработки. Его появление подтверждает, что React можно скормить любой движок для рендеринга виртуального дома дерева. Первая имплементация этого подхода была результатом хакатона и в итоге продолжила свое развитие в Open Source. На данный момент очень популярен не в последнюю очередь благодаря «Реакту» для Web.
Общая архитектура очень похожа на NativeScript, только мост на 100 метров выше по реке. Нативные плагины пишутся на стороне платформы, а через мост передаются лишь параметры. В промежутке между JS и платформой находится Yoga — кроссплатформенный движок, который реализует flex-box layout на целевой платформе.
Технически React Native очень похож на то, что frontend-разработчики привыкли видеть на Web.
Фреймворк активно развивается: релизы появляются каждые 3–6 месяцев. В версии 0.61.0 обновили механизм hot reload, который позволяет работать более производительно. Не так давно была выпущена версия 0.62.0, которая добавила интеграцию fbflipper из коробки. Надеюсь, эта инициатива получит достойное продолжение, так как до сих пор арсенал инструментов разработчика был похож на лоскутное одеяло. Изначально предлагается только консоль браузера, можно использовать также react-native-debugger или reactotron, которые дают дополнительные инструменты при разработке (инспекция Redux, MobX, Apollo Cache).
Из особенностей: иногда встречаются отличия при отображении в iOS и Android. В большинстве случаев все хорошо, но перед завершением разработки фичи стоит проверять на обеих платформах. Виджеты, предоставляемые платформой, иногда сильно отличаются. В случае переключателей механика и общий принцип работы одинаковы, в случае пикера отличия кардинальны. Если требуется подобная механика, приходится прибегать к услугам модулей.
Последними рассмотрим фреймворки native-like. Отличает их то, что они совсем не используют встроенных виджетов. Вместо этого рисуют все своими силами. Одним из новичков в этой категории является Flutter. В процессе подготовки статьи я с удивлением обнаружил, что с 2011 года на Python развивается аналогичный фреймворк, реализующий такую же концепцию, — Kyvi. Увы, но этому фреймворку не хватает финансирования и комьюнити. Например, имплементация Material UI уже 3 года не развивается, а инициатива была перехвачена нашим соотечественником.
Flutter
Первый релиз состоялся в конце 2018 года. Платформа достаточно молодая, но она активно развивается: ежеквартальные релизы, активное развитие языка Dart, богатый инструментарий разработчика, изумительный hot reload, онлайн-редактор для анимации, специализированная CI/CD — все это было доступно с первого дня релиза версии 1.0.
Особенностью архитектуры Flutter является то, что он сам рисует каждый пиксель, контролирует жесты и анимацию. Он не использует ОЕМ-виджеты, как это делает React Native. Вместо этого команда Flutter создала два набора виджетов для основных мобильных платформ: Material для Android и Cupertino для iOS. Таким образом, они заново отрисовали все UI-компоненты с обеих мобильных платформ, полностью повторив их поведение. Непосредственно с мобильной платформой (геолокация, звук, Bluetooth) взаимодействие происходит через Platform Channels.
Благодаря такой архитектуре заявлена поддержка «всего что угодно», в теории. На практике хорошо поддерживаются iOS и Android. Активно развивается Web. Фактически успех на web-поприще определит дальнейшую популярность фреймворка во всем мире. На данный момент есть поддержка Web в бета-версии, и с каждым днем она становится все лучше. Одной из проблем является производительность. С флагом FLUTTER_WEB_USE_SKIA=true производительность существенно возрастает. Более подробный обзор Flutter доступен в моей предыдущей статье.
Относительная «молодость» платформы и широкий перечень поддерживаемых платформ, бывает, преподносит баги в неожиданных местах. Благодаря быстро растущему комьюнити на многие из них есть ишьюс на GitHub, в которых часто можно найти вариант обходного решения проблемы.
Qt
С этим фреймворком мне еще не довелось плотно познакомиться. На всякий случай я его установил и запустил. Не без проблем — из-за бага, который благополучно пофиксили в версии 5.14.2. В комментариях отпишитесь, если у вас есть опыт кроссплатформенной мобильной разработки на Qt.
Тренды
Для полноты картины приведу тренды на Stack Overflow:
Вакансии (Djinni):
- React Native — 45.
- Flutter — 19.
- Xamarin — 4.
- Cordova/Ionic — 1.
- NativeScript — 0.
Муки выбора
Выбор конкретного решения будет продиктован, скорее, не плюсами и минусами фреймворка, а общей картиной и целями на проекте. Кроссплатформу можно назвать компромиссом между созданием отдельных команд разработки и получением качественного результата. Также кроссплатформа подходит стартап-проектам. В обоих случаях вы будете выбирать исходя из того, что имеется в активе, а не ради перспективы получения сферически идеального продукта. Под активом подразумевается существующий продукт (код, который можно заново использовать), компетенции сотрудников, популярность фреймворка (наём новых сотрудников, развитие фреймворка и плагинов).
Например, если у вас десктоп-решение на .NET, ваш выбор, скорее всего, падет на Xamarin, что позволит эффективно заново использовать имеющиеся наработки и компетенции.
Если вам нужно простейшее решение, чтобы текущий web-продукт поддержать мобильной платформой, вам подойдут PWA или Ioinc (с дистрибуцией через магазины).
Если вы только за Angular либо за React, а все остальное — «фу-фу-фу», если нет времени или желания разбираться, а нужно приложение на вчера, вы, скорее всего, остановите выбор на NativeScript в первом случае или на React Native во втором.
Стартапам придется выбирать между React Native и Flutter из-за их популярности и поддержки большими компаниями. Первый — это зрелый фреймворк с устоявшимися практиками разработки, богатством библиотек и большим комьюнити. Второй — молодой, быстрый и перспективный с богатым набором встроенных UI-компонентов и крутым developer experience.
Начинающим разработчикам или желающим попробовать что-то новое стоит обратить внимание на Flutter.
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]