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

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

Чтобы понять, где и какой тип разработки будет удобнее, я пообщался с Head of iOS в Tango, CTO/Founder в Seagull, Александром Поддубным. Он рассказал о нюансах разных подходов. Эта информация позволит понять, какой подход будет предпочтительнее в том или ином случае.

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

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

Можно ли сравнивать производительность нативных продуктов с производительностью кроссплатформенных?

Лично я бы не стал, т.к. давно все для себя решил. Но сравнивать всегда можно и нужно, именно здесь и находится истина. Такой инструмент как Component Kit, прародитель React Native, в свое время показал нам, что такое высокая производительность по сравнению с обычными нативными инструментами. Но это был лишь кейс, свойственный самому Facebook, который породил обе этих технологии. Большинство других остаются по-прежнему не оптимизированными, и сложно говорить о том, как они поведут себя в случае с вашим приложением.

Если кроссплатформенные фреймворки обладают производительностью ниже нативных языков, то насколько это будет заметно для пользователя?

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

Как выстраивается работа с вычислительной подсистемы устройства в кроссплатформенной среде? Нужны ли для этого нативные средства, насколько велико их присутствие?

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

Во всех ли случаях работы с вычислительной подсистемы смартфона нужны элементы нативной разработки? Если нет, приведите примеры, в которых такое взаимодействие обеспечено библиотеками фреймворка (например, React Native или Flutter)

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

Правда ли, что во всех случаях при квалифицированной разработке нативное приложение будет компактней? Существуют ли способы уменьшения объёма до сравнимых величин при использовании кроссплатформенных методов?

Безусловно, если кроссплатформенный инструмент добавляется непосредственно к бинарному коду приложения, это очень сильно утяжеляет вес приложения, т.к. в таких технологиях обычно стараются покрыть практически все необходимые инструменты для разработчика. Если бы эти технологии преобразовывали ваши наработки непосредственно в финальный нативный бинарный код, то результат был бы лучше, но как известно, ни современные Flutter, ни React Native этого не делают. Оно и понятно: это еще более сложная работа, чем они уже сделали. Т.к. одно дело, используя верхнеуровневые скриптовые языки, преобразовывать их, используя нативные компоненты во время работы приложения, другое дело, перед компиляцией генерировать огромное количество кода. Напротив, при нативной разработке, разработчик может выбрать не совсем подходящие для него посторонние библиотеки, либо использовать их там, где можно было бы обойтись парой десятков строк своего кода, тем самым увеличивая размер приложения на их объем, а они могут быть крайне большими, т.е. в этом случае это излишне. Что касается уменьшения объёма, то здесь, по сути, все те же подходы, что и в нативной разработке: избавиться от неиспользуемых ресурсов, кода, компилировать приложение под нужную архитектуру, там где это можно, избавляться от debug символов и так далее.

Существует ли удачно реализованные способы взаимодействия с низкоуровневыми функциями устройства в кроссплатформенных фреймворках, не требующих использования элементов нативной разработки? Например, функции шифрования при финтех разработке или работы с аппаратной частью смартфона?

С учетом того, что кроссплатформенные приложения занимают не самое последнее место на рынке, безусловно, эти инструменты широко представлены в сети. Особенно я бы хотел отметить React Native и подобные инструменты, использующие JavaScript внутри. Т.к. это изначально родной язык для веб-разработки, а веб-разработка всегда шла вровень с развитием криптографических продуктов. Здесь вы найдете великое множество сторонних библиотек с уже давно стабильной реализацией тех или иных алгоритмов.
Что касается аппаратной части смартфона, увы, реалии таковы, что год от года вендоры платформ вводят дополнительные возможности, старые функции остаются без поддержки, постоянно вводятся какие-то ограничения с точки зрения безопасности, и быть уверенным в том, что кросс-платформенный продукт позволит вам быстро поддержать новые изменения, которые, возможно, годами делались огромным штатом разработчиков Apple или Google, не стоит.

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

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

Насколько, по вашей оценке, выше трудозатраты при работе нативными языками, по сравнению с кроссплатформенной разработкой? Сколько времени можно выиграть?

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

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

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

Каким проектам вы могли бы порекомендовать кроссплатформенную разработку, а каким нативную? Уточните основные факторы, на основе которых вы даёте именно такие рекомендации. Уточните в каких случаях, по вашему мнению, возможны варианты, а в каких – нативные языки или фреймворк обязательны.

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

И здесь, собственно, появляется самое главное обоснование существования этих технологий. Не у всех есть безлимитное количество денег и времени. Особенно, если мы говорим про малый бизнес. В большинстве случаев малый бизнес уже имеет или планирует завести веб приложение (сайт), а предполагаемое приложение будет являться его полной копией. В таком случае, безусловно, кроссплатформенный фреймворк будет максимально выгоден. А если это веб приложение было на React.js, мобильные будут делаться на React Native, а сайт уже поддерживает мобильную верстку, то у вас по сути 10 из 10. Также, если ваш выбранный кроссплатформенный фреймворк был создан для каких-то конкретных нужд, как, например, React Native создал Facebook для того, чтобы унифицировать веб и мобильные команды, и это ровно ваш случай, и вы пишете второй Facebook, то это точно ваш выбор.

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

Как вы оцениваете возможность кроссплатформенных фреймворков создавать веб и десктопные приложения?

В свое время я увлекался разработкой macOS (тогда еще OS X) приложений. Но если вспомнить опыт Microsoft с появлением гибрида Window Mobile и Desktop, если взять в расчет то, что Apple уже сейчас в течении нескольких лет начинает плавную интеграцию мобильных операционных систем с настольными, а теперь мы видим еще и самое зарождение унификации процессорных архитектур среди мобильных и настольных операционных систем, то недалек тот день, когда они будут одно целое.

Мы можем взять печальный опыт такого приложения как Slack, который при наличии какого-то количества различных workspace в свое время начинал съедать абсолютно всю оперативную память настольного устройства, всё это камни, о которые мы бьемся в начале этой эпохи. Похожие ему приложения, которые по сути являются каким-то чатом, или, пускай, это будет планировщик задач, календарь, калькулятор, в конце концов. Этим приложениям навряд ли нужны нативные инструменты. Да и зачем? Если вы задумали такое приложение, у вас уже 100% есть или мобильное, или веб приложение. Либо вы можете просто переиспользовать вашу логику, либо начать заново сразу на кроссплатформенном фреймворке. Тем более, что нативные инструменты для десктопа морально устарели.

Их, конечно, пытаются актуализировать с годами, но проблемы остаются те же. Но, если вы, например, разрабатываете игры, то нативные инструменты точно еще далеки от нужд. Да и сама разработка игр, по сути всегда была кроссплатформенна: либо используемый движок непосредственно работает с системными драйверами, либо вы сами его пишете, а все, что касается физики или рендеринга, уже давно запечатлено в великом множестве сторонних библиотек, хоть на Java, хоть на C++. Похоже на мобильный кроссплатформенный подход, не правда ли? Но это, совсем другая история.

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

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

Изложенное Александром безусловно не истина в первой инстанции, но достаточно аргументированное мнение компетентного специалиста. Возможно у вас есть свои представления о возможностях и преимуществах кроссплатформенной и нативной разработки. Если это так — поделитесь своим мнением в комментах, я всегда рад продуктивной дискуссии.

0
12 комментариев
Написать комментарий...
Vovan Avach

Если бы яблочная секта не ограничивала прогресс pwa то выбор был бы очевиден так как доступность и сроки решают.

Ответить
Развернуть ветку
Yuri Trenin

Замысел статьи совсем некорректен - все же антагонист native  - это web app. И главная разница в ограниченном для web app / pwa доступном через браузер API и в отсутствии необходимости биться с яблочным App Store Review team и создавать недешевую инфраструктуру разработки для данной дурнопахнущей экосистемы, застрявшей в 2010-х как по идеологии так и дизайну UI (привет, iOs 15).  

А тот же flutter, react native или, прости господи, xamarin не факт что всегда будут выполнятся на js vm  и страдать худшей производительностью в специфических сценариях. В большинстве случаев приложение хоть нативное, хоть условно нативное на js vm, хоть PWA - всего лишь тонкий клиент c кэшем к UDP / TCP / WEBRTC / HTTP/3 /etc. сервису. Хорошая архитектура никогда не будет заниматься ресурсоемкими вычислениями на устройствах с ограничением по запасу ЭЭ в 5 ампер*часов в лучшем случае.

Поэтому нужна все-таки новая статья Native/NativeJSVM vs PWA. Очень будем ждать!

Ответить
Развернуть ветку
Mihail Shalanin
Автор

Критика принята к сведенью. Согласен, что описанный ракурс проблемы актуален. В защиту материала могу сказать, что на практике вопрос в текущей постановке остаётся актуальным, так как клиенты о NativeJSVM и PWA не очень знают и, соответственно, не рассматривают их как часть стека будущего продукта. 

Ответить
Развернуть ветку
Валера Смирнов

Считаю что для mvp пойдет и кроссплатформенное решение. Если что то серьезное, то натив

Ответить
Развернуть ветку
Anfer

Каждый заказ уникален.

Если ты понимаешь что у тебя типичный круд, то ты можешь выиграть до 90% стоимости одной платформы.

Также автор не упомянул поведение, которое в итоге получается идентичным. Визуалка которая тоже выходит идентичная. 
Для многих заказчиков - это важно.

Выпускать одно приложение, а не 2 по факту.

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

Как бы все ситуативно. Реакт - медленный, флаттер развивается, Котлин натив в альфе? Мы на этапе зарождения. Учим и ждём.

Ответить
Развернуть ветку
Mihail Shalanin
Автор

Расскажите, что именно флаттер предлагает в коробке такого, что в нэйтив разработке делается костылями?

Ответить
Развернуть ветку
Алексей Компанец

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

Ответить
Развернуть ветку
Ivan P.R.

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

Ответить
Развернуть ветку
Jeka Butik

Упопе)
И почему один? А натива два?

Ответить
Развернуть ветку
Алексей Компанец

один потому что он пишет на JS (TS). Все остальное автоматом собирается под разные платформы. А для натива нужен отдельно разработчик под Android  и отдельно под iOS

Ответить
Развернуть ветку
Mihail Shalanin
Автор

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

Ответить
Развернуть ветку
Anfer

SliverFillRemaining например

Ответить
Развернуть ветку
9 комментариев
Раскрывать всегда