Нативная разработка, React Native и Flutter: критерии выбора

    Уже на стадии проектирования мобильного приложения важно понимать, какой язык выгоднее использовать для конкретного проекта. Наряду с нативной разработкой (например, для iOS — Swift или Objective-C, для Android – Java или Kotlin), используются кроссплатформенные фреймворки, такие как React Native и Flutter. Мы в SimbirSoft предлагаем несколько критериев, которые помогут в выборе как бизнесу, так и мобильному разработчику.



    Проблема выбора


    В мире уже около пяти миллиардов смартфонов, по разным оценкам, до 80% из них используют операционную систему Android, и менее 20% – iOS. И все же в каждой стране есть свои особенности, так, в США более 65% смартфонов работают на iOS. При создании мобильных приложений чаще всего требуется выпустить версии как на iOS, так и на Android. Для этого можно обратиться к нативной или кроссплатформенной («гибридной») разработке.

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

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

    — React Native от Facebook
    для приложений iOS, Android и Windows
    использует язык JavaScript и библиотеку React.js как основное средство разработки.

    — Flutter от Google
    для приложений Android, IOS и Fuchsia (подробнее см. нашу статью на Хабре)
    использует язык Dart, который также служит для веб-программирования.


    Популярность React Native и Flutter растет, хоть и с разной скоростью, согласно статистике Google Trends.

    Нативная разработка


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

    • стабильная и быстрая работа приложения;
    • максимальный срок жизни приложения;
    • приложение более гибкое и масштабируемое, благодаря использованию «родных» инструментов;
    • меньше ограничений в архитектуре и функциях;
    • интерфейс в точности соответствует платформе.

    Гибридная разработка


    Кроссплатформенные фреймворки «подгоняют» приложение под несколько операционных систем, поэтому нет необходимости создавать уникальные элементы для каждой платформы. В результате:

    • нужно меньше специалистов;
    • уходит меньше времени и ресурсов;
    • скорость разработки повышается.

    Если логика приложения одинакова на всех платформах, а интерфейс простой, гибридная разработка помогает быстрее вывести продукт на рынок. Мы рекомендуем такие фреймворки, как React Native и Flutter, при следующих условиях:

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

    Критерии выбора Native, React Native и Flutter


    Для бизнеса


    1. Доступность


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

    Native

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

    React Native и Flutter

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

    Мы рекомендуем бизнесу нативные технологии, когда приложение рассчитано на продолжительную работу (иначе говоря, “срок жизни”). Также это выгодно при наличии потребности в высокой производительности, сложном интерфейсе и анимации, низком энергопотреблении, интеграции со сторонними ресурсами (API и др.). Нативные приложения более выгодны в перспективе за счет снижения затрат на техническую поддержку.

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

    Памятка для бизнеса:

    для сложных приложений – рекомендуем нативную разработку;
    для простых приложений – гибридную.


    2. Скорость + соответствие задаче


    Время вывода на рынок (time-to-market) определяется, в первую очередь, размером доступной команды и особенностями мобильного приложения.

    Работа с кроссплатформенными фреймворками может оказаться выгоднее и быстрее, если приложение простое, с одинаковым UI, без платформо-специфичных деталей, таких как доступ к камере, работа с файловой системой и отпечатками пальцев, runtime permissons. Здесь гибридная разработка позволяет сэкономить время за счет вторичного использования практически всего кода и UI под две платформы. Однако, при необходимости создания сложных кастомных view кроссплатформенная разработка замедляется.

    Говоря о времени разработки мобильного приложения, важно понимать, что не существует “среднего срока по больнице”. Например, мы в своей практике выпустили банковское мобильное приложение за 100 дней, сейчас мы участвуем в дальнейшем развитии этого продукта. Вместе с тем были и простые приложения (срок запуска – около двух недель), и масштабные проекты со сроком разработки более года.

    3. Безопасность и перспективность


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

    В вопросе надежности нативная разработка опережает всех своих конкурентов. Развитие основных библиотек идет не один год, в них уже исправили большинство багов, нативные языки – такие, как Java, Objective-C, Swift, Kotlin – постоянно развиваются. Среди мобильных разработчиков можно услышать мнения, что в 2020-х годах нативную разработку на Android частично вытеснит Flutter, но пока это всего лишь предположение.

    React Native предоставляет все инструменты для создания безопасных мобильных приложений, пример тому – Skype, Instagram, Facebook и другие известные продукты. Опасения за безопасность возможны только при использовании сторонних модулей при разработке. При этом JavaScript активно развивается, выпускаются новые фичи, в обозримом будущем риск устаревания минимален.

    В случае разработки на Flutter риски выше, поскольку фреймворк молодой, релиз вышел только в декабре 2018 года. Пока что бывают проблемы, например, в тот или иной момент сборка библиотек доступна только под одну платформу, случаются сбои в Android Studio, есть баги в некоторых плагинах и библиотеках. С другой стороны, все это дорабатывают и исправляют. Нельзя исключать риск, что Google прекратит поддержку Flutter, как это уже было с другими проектами компании. Однако, на Flutter написана Fuchsia OS, в которой некоторые разработчики видят замену Android.

    Для разработчика


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

    — Уровень знания нативных языков и предпочтения команды

    Каждая мобильная студия имеет свои предпочтения в выборе технологий. Нативная разработка требует максимально полного знания соответствующих языков. Однако, благодаря использованию нативных средств систем, меньше ограничений и сложности при кастомизации или осуществлении доступа к платформо-специфичным инструментам (в отличие от React Native и Flutter). При наличии опыта в JavaScript мобильный разработчик может довольно легко перейти на React Native (не нужно дополнительно изучать язык Dart, как в случае с Flutter) или на Dart (большим плюсом будет знание TypeScript).

    React Native под капотом задействует нативные модули. Как следствие, если возникает потребность в кастомизации (и это не поддерживается из «коробки»), необходимо работать с модулями native. Например, в нашей практике был случай, когда приходилось кастомизировать библиотеку Яндекс.Карт для вывода кастомных визуальных составляющих на карте.

    Flutter, в отличие от React Native, выделяется собственным графическим движком. С одной стороны, это позволяет при разработке простых приложений вообще не касаться native. С другой стороны, при необходимости обращения к native это означает дополнительные сложности (например, обмен сообщениями с элементарными типами данных и JSON) и невозможность использования графических компонентов native.

    — Порог вхождения

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

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

    “Шпаргалка” для выбора


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



    Рекомендации


    Если выбор сделан в пользу фреймворков, мы советуем обратить внимание на следующие аспекты работы:

    Оценка

    Тестировать нужно все задействованные платформы (iOS, Android). Важно объективно оценить уровень знаний и опыт всех участников проекта, чтобы оценка в часах не оказалась заниженной. Предусмотрите риск появления багов в самих фреймворках React Native и Flutter во время разработки.

    Дизайн

    Некоторые элементы сложно (или вовсе невозможно) отрисовать в Flutter или React Native. По этой причине дизайн обязательно согласовать с разработчиками – причем до того, как заказчик влюбится в прекрасно отрисованную картинку.

    CI / CD

    На React Native не исключены специфические проблемы с автосборкой (например, из-за установки библиотек на разные платформы). Нужно заложить больше рискового резерва.

    Splash screen

    Реализация splash screen на Flutter происходит быстрее, чем на React Native, где этот элемент можно отрисовать лишь нативно, с большой вероятностью возникновения багов. При использовании React Native на splash screen со всеми отрисовками и багофиксами желательно заложить больше времени.

    Верстка

    При использовании React Native верстку на iOS и Android нужно проводить одновременно, чтобы в дальнейшем избежать проблем при адаптации верстки под одну из систем.

    Параллельная разработка web и mobile

    Если веб-версия приложения написана на React, меньше расход времени на разработку мобильного приложения на React Native – за счет одинаковой логики компонентов.

    Debug

    Если приложение большое, на React Native проще провести тестирование и юнит тесты. На Flutter нужно закладывать больше времени на багофикс, поскольку логи не информативны.

    Работа приложения с файлами системы

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

    Доставка сборок клиенту

    Здесь нет существенных отличий от нативной разработки, можно выбрать любой удобный сервис: Crashlytics, TestFairy, TestFlight.

    React Native vs Flutter


    Мы в SimbirSoft используем как React Native, так и Flutter, в зависимости от характера приложения. Делимся несколькими наблюдениями из нашей практики, которые помогают предусмотреть особенности работы с тем или иным фреймворком.



    Подводя итоги


    Разработка нативных и гибридных мобильных приложений обладает своими преимуществами и недостатками, которые учитываются бизнесом и исполнителем при выборе технологии. В числе наиболее значимых критериев – сроки и стоимость разработки и сопровождения, соответствие задаче, безопасность и перспективность, уровень развития комьюнити. Опираясь на свой опыт, мобильный разработчик помогает подобрать оптимальное решение для каждого конкретного приложения. Надеемся, что наши критерии и сравнительная таблица были вам полезны. Спасибо за внимание!
    SimbirSoft
    90,72
    Лидер в разработке современных ИТ-решений на заказ
    Поделиться публикацией

    Комментарии 24

      +3
      Работа с камерой и отпечатками пальцев в RN нормально реализована, с чего вдруг там риски?
      Еще 2 года назад все работало отлично, не думаю что что то поменялось.

      Splash screen это вообще на уровне native настраивается, что вы за бред пишите?

      «При использовании React Native верстку на iOS и Android нужно проводить одновременно»… а что, во Flutter/native/web она сама волшебным образом встанет как надо? Странная логика

      Статья написано тем кто мало понимает в том о чем пишет.
        +1
        Добрый день. Риски в RN связаны с нативными библиотеками и могут проявляться, например, при работе с разными версиями ОС и моделями телефонов.

        Да, как мы и пишем, в Splash screen отрисовка происходит нативно, все верно.

        Если в вашем проекте нет необходимости строго соблюдать стили Android и iOS, вы можете ограничиться одним вариантом верстки. Если дела обстоят наоборот, придется повозиться с каждым вариантом отдельно. Один и тот же код верстки на RN может по-разному работать на iOS и Android, поэтому в процессе верстки нужно смотреть, как все работает на обеих платформах.
          0
          Если «Splash screen отрисовка происходит нативно» то зачем о возможных проблемах с нам у RN? Там нет RN / Flutter кода, это делается в AndroidManifest / LaunchScreen.xib, не вводите в заблуждение.

          «Риски в RN связаны с нативными библиотеками и могут проявляться, например, при работе с разными версиями ОС и моделями телефонов»… так риски с RN или с нативными библиотеками? Сборка андроид приложения сейчас тоже напоминает танцы с бубном, когда начинаются конфликты зависимостей
          0

          https://github.com/react-native-community/react-native-camera/issues


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

            0
            В нативе проблем тоже много

              0
              Потому CameraView deprecated. Смотрите в сторону CameraX (как и указано в readme) или в сторону Camera2 API. Там тоже, конечно, есть свои проблемы, но эти инструменты производительнее и более гибкие
          0
          Для полной картины сравнения нативной и гибридной разработки неплохо был бы добавить и Kotlin Multiplatform. Технология хоть и совсем новая, но зато позволяет создавать нативные для платформы приложения и иметь единую базу кода для основной логики.
            0
            Это было бы не совсем корректно. React Native и Flutter позволяют создавать приложения от начала и до конца, включая UI и его поведение. Kotlin Multiplatform хорош для общей бизнес-логики для нескольких платформ, но UI и UX реализации ему нужны сторонние. Например, нативные или интеграция с Flutter
              0
              Да, абсолютно верно, но мне как и некоторым другим людям из комментариев, не хватило вариантов совмещения нативной и кроссплатформенной разработки. Вроде здесь говорится вообще о разработке приложений в целом, а не только про UI и даются рекомендации по выбору технологического стека. Так что упомянуть другие варианты, как мне кажется, не лишнее.
            0
            А Вы рассматривали вариант без крайностей native ИЛИ гибрид? На данный момент я участвую в разработке приложения, где наиболее используемые экраны где нужны анимации и производительность пишем native. А все остальные делаем во flutter. И на этот формат мы переходим постепенно из двух полностью нативных разработок (iOS + Android)
              0
              Да, предложенный вами вариант подходит для некоторых кейсов, совмещение нативной и кроссплатформенной разработки возможно. Как правило, кроссплатформенная разработка служит для того, чтобы снизить затраты на проект. При выборе способа разработки мы учитываем несколько взаимосвязанных критериев, таких как сроки и бюджет, задачи конкретного приложения, наличие специалистов. В статье мы описали решения, которые выбирали для отдельных кейсов – это не «серебряная пуля» и единственно верный гайд для разработки.
              0
              В чём проблема написать часть приложения (ту, где RN / Flutter не справятся) в Native? Зачем полностью отказываться от кроссплатформы, только потому, что не хватает какого-то функционала, если эта проблема легко решается?
                +1
                Зависит от задачи и от количества итогового платформозависимого кода.

                Проблема задачи в том, что RN и Flutter основаны на подходе bridge-коммункации. Сам по себе этот bridge зачастую медленный. Он достаточно быстр для взаимодействия с большинством компонент, но при большой нагрузке может стать бутылочным горлышком.
                Плюс если есть требования к размеру приложений (например, нужен Instant Apps) или к его взаимодействию с пользователем (например, управление на Apple TV и Android TV), то кроссплатформенные фреймворки сегодня не смогут предоставить подходящего решения.

                Проблема в количестве платформозависимого кода состоит в том, что если его доля в проекте переваливает за 40-50%, то встает вопрос о надобности кроссплатформенного фреймворка в принципе. Соотношение время-деньги-качество получается уже не таким вкусным в сравнении с нативной разработкой. То есть две команды нативных разработчиков обойдутся дороже, но с реализацией справятся быстрее, а итоговое решение будет более отзывчиво себя вести и (при желании заказчика) соответсвовать гайдлайнам (что позволит привлечь или удерживать часть аудитории за счет привычного UX).
                В итоге время здесь часто более важный фактор чем деньги. Раньше выйдешь на рынок- отхватишь больший кусок.
                0
                По react native было бы корректно упоминуть Expo. Много модулей, поддержка iOS, Android, Web (бэта) платформ. А ещё есть React Native for Windows от MS. В итоге за RN — больше платформ.
                  0
                  Действительно, Expo – один из вариантов создания кроссплатформенного приложения, он подходит для реализации микрофункциональных фич и их демонстрации клиенту в качестве прототипа. Однако, есть свои ограничения. Начало проекта на Expo с последующим переходом на native может повлечь за собой ряд проблем, от верстки до замены вшитых библиотек Expo на нативные библиотеки.

                  Что касается React Native for Windows, в этой статье мы не акцентировали внимание на разработке десктопных приложений. В целом, библиотеки windows и web пока достаточно сырые, но в долгосрочной перспективе могут получить должную поддержку.
                  +1
                  Автор с первых строк не совсем корректно сравнивает нативную разработку и ее преимущества с широкой экосистемой кросс-платформенной разработки. И это печально.

                  Сразу разделите гибридные решения на основе WebView (Phonegap/Cordova, Ionic) от гибридных решений типа React Native, Flutter, Xamarin. Это технически абсолютно разные направления. Одинаковые только концептуально (один код — разные платформы).

                  Во вторых — сервер здесь не при чем. Приложения нативные или гибридные — все они работают offline. Это изначально условие для любых приложений, которое может нарушаться только концептуально (например, Инстаграмм или Фейсбук или остатки на складе в реальном режиме времени).

                  Итак, для начала стоит ответить на простой вопрос: в чем отличие <View /> в React Native от нативного UIView в iOS и View в Android? (подсказка: Ни в чем. <View /> трансформируется в UIView или во View в зависимости от платформы)

                  Поэтому сравнивать UI сделанный в React Native с UI сделанный в XCode или Android Studio нельзя. Это одно и тоже (по качеству, производительности, кастомизации). И это касается всех элементов. Нет, правда всех. React Native даже Date Picker отображает, путем вызова конструктора нативного picker для каждой платформы. А Animate API, direct manipulation, useNativeDriver? Удивительно, но на уровне платформ разницы тоже нет. Да, создание компонента прилетело из декларативного описания, но компонент-то нативный и анимация тоже. И еще вопрос на засыпку, кто сегодня не выдумывает колеса или не использует решения с декларативным описанием интерфейса, вместо drag and drop в среде разработки?

                  Если копнуть глубже, там где требуется нативный код, то да — надо писать исключительно для платформы, нативно. Когда мы говорим «глубже», это глубже, чем камера, файловая система, отпечатки пальцев, карты. Короче это не простой доступ к hardware, с которым ни у React Native ни у Flutter вопросов нет. Даже Phonegap/Cordova давно решили эти проблемы с нативными плагинами (с переменным успехом и стабильностью), но не решили проблемы с производительностью WebView.

                  Ни RN ни Flutter не считают прямой доступ к нативному API за bad practices там, где это действительно необходимо и дают все инструменты для этого, не ограничивая. Зато reusable-код штампованной бизнес-логики впечатляет настолько, что даже <Button /> и <ButtonIOS /> на каждом шагу не очень расстраивают. Даже OpenGL в React Native и нативной разработке — это одна библиотека и частота кадров будет зависеть только от того, как быстро работает логика в каждом фрейме (и вот только здесь-то JS в виртуалке может уступить нативному коду).

                  Приведите один пример из своего опыта, где «глубже» это действительно что-то за рамками простого доступа hardware, карт? Может быть, сложная обработка изображений за границами популярных фильтров? Про UI уже сказал выше, повторюсь — не сравнивайте, это одно и тоже.

                    0
                    Даже реализация доступа hardware не так уж проста. В частности, в flutter для взаимодействия с нативной частью нужно создавать каналы для передачи данных и дублировать сущности в нативной части. Хорошо, когда есть библиотека, в которой это сделано. Однако, не всегда это возможно. Бывает, что на каких-то устройствах обнаруживаются баги. Бывает, что функциональность не в полной мере соответствует потребностям. Аналогично с RN: что-то работает на iOS, но не работает на Android – и наоборот. Кроме того, есть разница в производительности. Чем больше анимированных элементов на экране, тем ниже производительность (или потребуется дополнительное время, чтобы сделать все без тормозов)
                      0
                      Насколько я знаю из собственного опыта, баги на разных устройствах и разных версиях платформ обнаруживаются не только в библ. для RN/Flutter но и в нативной разработке и тут даже разраб. под отдельную платформу приходится туго (больше касается android). Возникает дилемма: наполнить код if/else для каждой версии или слегка «забить» на пользователей старых версий. В кроссплатформ. разработке аналогично поступают и разработчики библ. Ну, обобщая — это общий вопрос.

                      Разница в производительности? Логика, UI? На вопрос «Чем больше анимированных элементов на экране, тем ниже производительность» попробуйте сами ответить с оглядкой на то, что в итоге происходит рендеринг нативных компонент, не важно RN/Flutter или сборка со среды разработки Android Studio / XCode. Ну, полно сравнительных тестов и результат таков, что даже RN где-то выигрывает (при этом процент прироста настолько мал, что можно пренебречь). Смысла нет сравнивать нативные UI, один из которых построен декларативно, другой — «нативно» drag&drop в среде разработки.


                        0
                        Со всем выше согласен, кроме разницы работы UI. RN по факту всегда медленнее на списках и сложных экранх из-за реализации рендера, а именно -> основный поток JS, который и запросы кидает, и бизнес логику, и рендеры запускает -> все рендеры идут в shadow dom, который еще и сравнивает, а не изменилось ли что? -> только потом идет нативный рендер. Как не трудно догодаться именно проброс из JS в shadow DOM является бутылочным горлышком всей системы. Особенно, если при открытии экрана происходит догрузка данных, после чего, появление новых элементов происходит с анимациями — это 100% тормаза на Android, iOS с этим справляется на много лучше, как и во всем RN, кстати.

                        p.s. сам уже 2.5 года пишу на RN, на данный момент приложение с 350к+ уникальных пользователей в месяц (iOS и Android)
                          0
                          О списках спорить не буду, тем более нагруженный рендер позиции может быть причиной тормозов и трудно представить, что его можно вынести за мост на нативную сторону. Правда, в документации RN указывается на асинхронный рендер и связанное с этим поведение и выгоды (пробелы при очень быстром скролле, сам скролл без тормозов).

                          Основной поток JS должен заниматься запросами и бизнес логикой, перед этим запустив анимацию. Если анимация нативная (Animated), то ей все равно, чем занимается основной поток JS. Запустите анимацию с usingNativeDriver и заблокируйте основной поток JS и увидите, что анимация не прерывается.

                          С Shadow DOM уже заинтересовали и тут вопрос — React Native использует Shadow DOM? Это же не React в среде DOM, как тогда? Если есть пруфы буду рад почитать.

                          Мы можем миновать state в узких местах и избежать сравнивания дерева, React Native дает инструменты для этого.

                          Понять из-за чего происходят тормоза при дозагрузке данных на Android, поможет только отладка и счетчики произв. Уверен, что при передаче анимации и запросов в БД на нативную сторону проблема начинает проявляться уже там. И тут надо подумать о принудительных задержках, например, дождаться запуска анимации, затем делать запросы и т.д.

                          Буду благодарен, если поделитесь ссылкой на приложение :)

                            0
                            В RN не конкретно Shadow DOM из веба, но своя анологичкая реализация:
                            When React start rendering Reconciler starts “diffing”, and when it generates a new virtual DOM(layout) it sends changes to another thread(Shadow thread).

                            Подробнее почитать можно тут.

                            А приложения вот:
                            Android
                            iOS
                    0
                    Странный у вас график в Google трендах: якобы в 2016 году и ранее flutter был популярнее React Native. Странный, потому что первый выпуск, согласно википедии, был в 2017 году.

                    Слово-то популярное, стоило бы уточнить область применения при запросе.
                      0
                      Вот более правильный график)
                      Кликать тута
                      image


                        0
                        Спасибо за уточнение)

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое