React Native vs Cordova vs KMM: что же выбрать бизнесу
На рынке мобильной разработки куча различных инструментов и технологий, и обычному человеку, даже программисту без опыта в этой сфере, очень сложно выбрать “ту самую” вещь, на которой стоит создать приложение. Автор постарался без негатива и предвзятости рассказать о всех интересных и важных вещах, которые, на его взгляд, полезно узнать интересующимся людям. Ну а выбор читатель сделает самостоятельно, ознакомившись c опытом автора. В конце будет небольшой итог состоящий из субъективного мнения автора.
React Native
React Native – это инструмент, который позволяет разработать кроссплатформенное мобильное приложение на базе языка программирования JavaScript.
Не будем ходить вокруг да около и сразу перейдем к интересным особенностям.
Тут нет HTML и CSS
Разработка на React Native не равно разработка на React. У Вас нет HTML, поэтому о привычной веб-разработке можно забыть. Вообще, при разработке на React Native придется использовать заранее заготовленные компоненты по типу: Text, View, InputText вместо привычных div и span. Ну и также тут нет CSS. Паниковать не стоит, нет “привычного CSS”, но есть местный эквивалент, который очень похож на обычные стили из веб-разработки.
Так что в начале пути надо всем разработчикам немного пострадать и “заучить” все эти особенности, чтобы быстро разрабатывать экраны.
JavaScript не транспилируется
Транспиляция – это процесс при котором исходный код одной программы переписывается на эквивалентный код, но на другом языке.
React (именно React) не связан с API DOM дерева как многие другие JavaScript фреймворки. Поэтому, когда мы ведем разработку на React, мы верстаем не на HTML, а на JSX. После, при сборке, JSX объекты превращаются в JavaScript код. То есть, создавая div в JSX на выходе получаем что-то типа:
React.createElement('div', null, null);
Поэтому все это позволило разработчикам React Native спокойно “модернизировать” React под себя. Они отлавливают все вызовы функций React.createElement и возвращают какие-то “объекты” от которых в реальным времени через функцию eval() порождаются нативные компоненты той операционной системы, на которой запущено приложение: на Objective-C для iOS или на Java для Android.
Скриншот выше является примером исполнения JavaScript внутри Swift. Вам ничего не мешает ловить результаты функций и отрисовывать нативные компоненты. Весь нужный функционал есть в ядре операционной системы iOS (в Android тоже есть).
Так что приложения, написанные на React Native, и правда получаются нативными. Правда все компоненты порождаются через десятки слоев абстракций и, скорее всего, это все влияет на производительность. Ну влияет же, да?
Производительность
Смотря с чем сравнивать. React Native очевидно медленнее нативного приложения, написанного на Swift/Kotlin/Java/Objective-C. React Native медленней приложения на KMM. Но точно React Native не медленнее приложений, написанных на Cordova.
У React Native есть проблемы, но мы бы не сказали, что они серьезные. Конечно, если Вы хотите как-то работать с графикой на прямую, этот фреймворк не для этого. В основном проблемы бывают, когда компонентов очень много и там куча разных эффектов.
Не все, но многие проблемы можно решить. Обычно корень всех бед находится в руках программиста, который “кодил” приложение. Для отладки таких проблем можно использовать сторонние библиотеки по типу why-did-you-render. Да, это не удобно, но придется смириться.
В целом почти любой кроссплатформенный инструмент всегда далек от идеала по производительности и проигрывает нативным технологиям. Проблемы есть, но нужно всегда выбирать между скоростью разработки и скоростью самого приложения.
Поддержка
React Native является детищем внутренней разработки компании Facebook*, поэтому о “причесывание” его в более менее потребный вид для продукта можете забыть. Этим занимаются другие сторонние компании – Expo, Software Mansion. Иными словами, поддержка тут никакая. Резкие изменения в функционале фреймворка? Да пожалуйста. Шероховатости, которые никто не исправляет долгое время? Получите и распишитесь. Ах да, это еще даже не финальная версия фреймворка, и, судя по последней версии (0.70), получается бета или даже альфа (и так несколько лет).
Несколько вариантов разработки
Чуть выше мы упомянули о том, что React Native не продукт, и его развитием занимаются многие другие компании. Это породило некоторые интересные вещи. Например, Вы можете создать приложение на “чистом” React Native, его называют Init. Или воспользоваться интересным решением от компании Expo, его так и называют – Expo.
Между ними много отличий, которые здорово бы изучить желающим начать что-то делать на этой технологии. Но, если говорить о самом главном, то можно выделить следующие интересности.
Во-первых, Init имеет меньше заранее заготовленных компонентов, о которых мы говорили в абзаце “Тут нет HTML и CSS”. Поэтому, что-то делать нам нем получается медленней, чем на Expo. Но и поэтому в среднем вес приложений, собранных через Init, в пять раз меньше чем в приложениях, собранных через Expo.
Во-вторых, рано или поздно Вам потребуется внедрить в свое кроссплатформенное приложение нативный функционал по типу push-уведомлений, своих компонентов или face/touch ID. На Init это сделать намного проще. На Expo это больно. Это очень больно. Это встанет бизнесу в такие деньги, что он пожалеет, что вообще начал делать приложение на Expo.
“Очень больно” – это слова человека с опытом нативной разработки. Обычно мы говорим клиентам, что на Expo невозможно сделать интеграцию с некоторым нативным функционалом, просто потому что это настоящий геморрой, который сложно без мата описать.
В-третьих, Expo достаточно закрытая платформа, поэтому, если к программисту придет отдел маркетинга и попросит внедрить аналитику, то ему скорее всего придется отказать, потому что она не будет поддерживаться. Ну а если Вы найдете какой-то баг, из-за которого приложение вылетает, то придется очень долго ждать патча, который его исправит. Ну или просто отказаться от функционала (если это будет возможно).
В-четвертых, для сборки любого кроссплатформенного приложения под iOS требуется MacOS и Xcode. Независимо от фреймворка. Но вот приложение, разрабатываемое на React Native Expo, позволяет этого не делать. Возможно, это плюс для кого-то, только вот цена у этого оказалась высока из-за появившихся проблем с интеграцией нативного функционала. Для сборки React Native Init обязательно потребуется MacOS и Xcode.
Cordova
Cordova – (или Apache Cordova) это технология, которая позволяет создать мобильное приложение с помощью веб-технологий: HTML, CSS, JavaScript. Мы даже как-то о ней писали отдельно статью. Если интересно, то почитайте, хотя и тут подробно все расскажем.
WebView
Cordova отличается от React Native тем, что программисты работают в привычном для себя ключе: верстают на HTML, CSS и JavaScript. Только на выходе получается мобильное приложение.
Если в React Native нативные компоненты в реальном времени через eval порождаются от Вашего JavaScript кода, то с Cordova все намного проще – приложение это “браузер”, которое отображает один единственный сайт. Тот самый, который Вы любезно сложили прямо в телефон (чтоб без интернета работал).
Программист создает типичное SPA/PWA-приложение, оборачивает его через ядро Cordova, которое при запуске приложения запускает WebView, отображающее SPA-приложение (ну или классический сайт, как сделаете).
WebView – это тулза (виджет) для открытия веб-сайтов, который есть во всех нормальных операционных системах. Т.е это не прямо уж браузер, это одна из составляющих браузера.
Вообще, браузер может состоять из нескольких экранов (настройки, закладки, скачанные файлы, истории), базы данных и WebView. Не знаем зачем Вам эта информация, но пусть будет.
Производительность
“И как тут все с производительностью?” – спросят многие. Да почти также как и в React Native. Сайт-то получается на localhost лежит, какие могут быть проблемы? Только с тем, что весь интерфейс рисуется через WebView и следовательно через HTML, CSS, JavaScript. Все ограничения, которые существуют в вебе, перекочуют и сюда. Все приколы JavaScript из браузера попадут к Вам в приложение. Само приложение открываться будет быстро, главное чтобы с интерфейсом самого приложения ничего не наворотили программисты.
Иными словами, если надо работать с графикой или с каким-то производительными операциями, Вам опять не сюда. Если делать SPA-приложение и строить весь интерфейс на реактивным фреймворках, то в целом у Вас получится прям настоящее приложение, которое мало кто отличит от сайта. Главное, чтобы у Вас были кадры, которые умеют в такую разработку.
В ядре Cordova нет никакого дополнительного функционала кроме WebView, поэтому приложения весят мало. Есть инструменты, которые позволяют расширять функционал приложения нативными плагинами добавляя поддержку камеры, push-уведомлений, геолокации и так далее.
Нативный функционал
Внедряется очень неприятно, но внедряется. Мы даже об этом писали несколько статей, вот пример. Да, это сложнее чем в React Native Init, но все еще в десяток раз проще чем издеваться над собой в React Native Expo.
Большое количество своих модулей так же влияет на производительность как в React Native. Из-за того что весь интерфейс рисуется через WebView, могут возникнуть проблемы. Сложно описать в каких кейсах, но при работе с камерой, push-уведомлениями, геолокацией, face/touch ID Вы лишь наткнетесь на них, но вот интегрировать решения они не помешают.
Любое решение, которое подразумевает “доработку” MainActivity (Android) или MainViewController (iOS), может вызвать жжение в пятой точке. Может даже придется “ломать” фреймворк. Повторимся, сложно сказать в каких конкретных кейсах, обычно это крайне нетипичные задачи, которые в кроссплатформенной разработке не очень жалуют.
Поддержка
Продукт развивает Apache Software Foundation. Проблем каких-то тут нет, ядро Cordova имеет маленький исходный код, поэтому получает постоянные нужные обновления. Не часто, просто по мере необходимости: поддержку новых SDK от Apple и Google регулярно завозят.
Kotlin Multiplatform Mobile
Kotlin Multiplatform Mobile – (или KMM) это инструмент, позволяющий на базе языка программирования Kotlin и Android Studio создавать мобильные приложения под iOS и Android (хотя MacOS и Xcode тоже понадобятся как и везде).
Особенности разработки
Автору статьи сложно ставить KMM в один ряд кроссплатформенных инструментов по типу Flutter, React Native и Cordova. Просто потому что это не привычная кроссплатформа, но и не совсем натив. Хотя технически это все еще кроссплатформа. Понимаем что не понятно, поэтому перейдем сразу к делу.
При разработке приложения под Android придется строить интерфейс классическим способом: XML и Kotlin. А при разработке под iOS интерфейс будете писать на… Swift. Внезапно, да? Если конкретней, то на Swift UI, который позволяет описывать многие вещи декларативно.
Но тут работа со Swift не заканчивается, а только начинается. Видите ли, структура KMM приложения состоит из:
- Kotlin модулей для Android: интерфейс и какие-то вызовы системных функций телефона по типу камеры или геолокации;
- Swift кода, описывающего интерфейс для iOS;
- Kotlin кода для iOS, который обращается к системным функция телефона (iPhone).
Думаем с последнего пункта многие просто офигели сейчас и даже пару раз перечитали правильно ли все они поняли. Да, все верно – “Kotlin код для iOS”. Вот пример того как на Kotlin обращаются к iOS библиотекам:
На скриншоте выше видно структуру простого KMM приложения. Конечно не полностью, но там примерно следующее: xml-файлы и Kotlin классы для интерфейса для Android, Swift классы для интерфейса для iOS, 3 “слоя” модулей для приложения:
- Kotlin код в папке androidMain для Android;
- Kotlin код в папке iosMain для iOS;
- Общий Kotlin код в папке commonMain, который объединяет два предыдущих “слоя”.
После, в файлах интерфейса (неважно Kotlin или Swift представление) импортируются модули из папки общих модулей и свободно используются. То есть, если посмотреть скриншот выше, то класс Platform() (из папки common) можно импортировать в Swift файл и получить результат. Но перед этим, класс нужно описать на Kotlin в папке iosMain. Ну и в папке androidMain если нужно. Иными словами, класс Platform() в папке common это интерфейс соединяющий iOS и Android код. Внимательно посмотрите на скриншот выше, там показан пример такой реализации.
Скорее всего у читателя на этом моменте взорвалась голова, поэтому мы здесь остановимся и для особо интересующихся программистов оставим ссылку на туториал по KMM. После того, как Вы сделаете свое “Hello World” приложение, все станет понятней. Из всего вышесказанного вытекают некоторые особенности KMM которыми хотелось бы поделиться.
Высокий порог входа
Чтобы начать делать мобильное приложение на KMM, надо быть знакомым с нативной разработкой на Android и желательно на iOS (ну или иметь сильное желание сделать это). Прошлые варианты же этого не требуют в полной мере и хватит знаний JavaScript и базовой работы с Android Studio и Xcode.
Программисты, пишущие на Kotlin для Android, значительно дороже своих собратьев на JavaScript, поэтому разработка будет дороже. Да и Kotlin сложнее JavaScript: это строго типизированный язык программирования не прощающий ошибки. Плюс достаточно кода придется писать на Swift, а он плюс-минус такой же по сложности. Хотя автор считает, что даже сложнее, потому что для русскоговорящего человека очень мало информации по Swift в СНГ сегменте интернета. Вся качественная информация доступна в основном в Google и на английском языке.
Сопоставления типов данных
Kotlin и Swift имеют разные типы данных, и программист регулярно будет сталкиваться с этим при написания кода общих модулей. Давайте объясним: программист пишет модуль в папке iosMain на Kotlin и внутри файла импортирует какую-то Swift/Objective-C библиотеку. Чувствуете возможные проблемы? Какая-то функция может вернуть из Swift тип данных nil, но мы ведь не сможем в Kotlin такое написать. В Kotlin нет такого типа данных, поэтому мы напишем null. А как нам узнать какой тип данных нужно указывать?
Дак вот, чтобы не было проблем создатели фреймворка предусмотрели сопоставление (или мапинг). Есть специальная таблица, в которую придется первое время очень долго смотреть и сравнивать типы данных.
Большая гибкость и потенциал
С одной стороны, все в этом фреймворке выполнено по канонам кроссплатформы, с другой стороны доступ к нативному коду платформы очень прост. Поэтому, интеграция нативных модулей тут – это максимально доступный процесс, который еще и можно упрощать. Со временем Вы будете “копить” общие модули и просто переносить их между проектами. С другой стороны, если лень такое делать, просто начните писать на Swift… или на Kotlin Native в нужном месте.
Производительность
Все будет работать на высоком уровне, потому что KMM собирает весь проект в нативный код платформы. Например, весь Kotlin код из папки iosMain будет переписан в Objective-C. Иными словами произойдет транспиляция и у Вас будет полноценное нативное приложение (а интерфейс и так нативно будете делать).
Поддержка
Развивает продукт компания JetBrains. Сообщество у KMM в данный момент маленькое. И вообще проект находится еще в альфа-версии (привет React Native). Из всех описанных здесь технологий лишь Cordova имеет релизную версию. Вся активная коммуникация происходит в общем чате в Telegram, там даже присутствуют разработчики инструмента и на наших глазах как-то обсуждали найденный баг программистом и впоследствии даже быстро его исправили. Но все равно есть вещи, которые долго не исправляют или не добавляют по разным причинам, недовольные люди тоже есть.
Хорошо это все или плохо – решайте сами. От себя добавим что если умрут все вышеописанные фреймворки, ну перестанут поддерживаться и обновлять SDK для iOS и Android, лишь приложение на KMM не умрет окончательно. Во всех других случаях Вам придется переписывать приложение с нуля на другие технологии, а с KMM будет проще: просто раздробите проект на iOS и Android версию и допишите некоторые модули на нужном языке программирования.
Итог
Подведем итог и добавим щепотку своего мнения. Мнение составлено из личного опыта, который сформировался после использования всех описанных технологий.
React Native
React Native подойдет для быстрого прототипирования приложения. Не самая высокая производительность компенсируется быстрой разработкой. Хотя, первое время придется “заучить” нужные компоненты, ведь HTML и CSS тут нет. Приложение по итогу будет нативным, поэтому компоненты могут выглядеть вкусно в операционных системах.
Разные версии для разработки приложений могут как усиливать его плюсы (скорость разработки), так и недостатки (производительность, вес, доработка). React Native Init более гибкий для интеграции с нативным функционалом, Expo имеет много готовых модулей, и разработка будет еще быстрее, хотя о своем нативном функционале Вы скорее всего забудете навсегда.
Ну и по опыту автора можно сказать, что рано или поздно почти все уходят из React Native, когда “стартап” стреляет. Так что, с вероятностью 90%, приложение все равно перепишите.
Cordova
Также подойдет для быстрого прототипирования приложения. Не надо переучивать сотрудников, легко интегрируется с Vue.js (есть Quasar). Можно объединить с любым реактивным фреймворком по типу Angular и Ember.
За отрисовку интерфейса отвечает WebView: это позволяет использовать всю мощь веб-технологий, но идет расплата производительностью. За интерфейс все цело отвечаете Вы (помним про HTML и CSS), поэтому, чтобы было вкусно, нужны хорошие фронтендеры.
Также как и React Native – временное решение.
KMM
Крайне сложный инструмент для разработки, поэтому компания должна уже иметь необходимые кадры, знакомые с Kotlin и Android. Один из самых лучших кроссплатформенных инструментов из существующих (в рамках мобильного сегмента самый лучший).
Быстро и дешево это не про него. Это инструмент для тех людей, кто реально знает что он делает. Для аутсорсинга или стартапа из-за дороговизны может быть плохим вариантом, хотя очень перспективным. А вот для продуктовой разработки очень даже хороший вариант, который можно рассмотреть в первую очередь.
P.S: Раздел итог – это субъективное мнение автора. Вы можете быть с ним не согласны, это нормально. Если нашли какую-то ошибку или хотите что-то добавить, оставляйте комментарий. Возможно, статью будем обновлять постоянно.
*Организация Meta, а также её продукт Facebook, на который мы ссылаемся в этой статье, признаны экстремистскими на территории РФ.
Оставьте комментарий