Дилемма разработчика: Flutter против React Native
2 апреля 2023 г.
Что мне следует использовать для создания следующего «убойного» мобильного приложения в 2023 году и как работают эти кроссплатформенные технологии?
Несколько лет назад, если вы или ваша команда решили разработать мобильное приложение для iOS и Android, вам нужно было поддерживать две базы кода, по одной для каждой платформы. Это означало либо обучение, либо наем разработчиков, хорошо разбирающихся в Swift и/или Objective-C (для iOS) и Kotlin и/или Java (для Android) — основные языки программирования, используемые для создания нативных приложений для этих платформ. Как вы понимаете, это не только увеличивает нагрузку на ваши ресурсы и бюджет, но также требует более длительных циклов разработки и кропотливых усилий по обеспечению согласованности между обоими приложениями.
С появлением в последние несколько лет кроссплатформенных сред разработки приложений разработчики мобильных приложений и компании все чаще переходят или, по крайней мере, рассматривают возможность использования этих технологий для создания своих мобильных приложений. Основная причина в том, что эти фреймворки позволяют разработчикам писать код только один раз и создавать его как для Android, так и для iOS. Поддержание единой кодовой базы значительно сокращает время запуска и обеспечивает высокий уровень согласованности между обоими приложениями. Мы подробно обсудим, как это стало возможным благодаря React Native и Flutter, которые на данный момент являются двумя самыми популярными кроссплатформенными средами разработки мобильных приложений. React Native — это проект Facebook (теперь мета) и был выпущен публично около двух за несколько лет до того, как Google выпустила первую версию Flutter в 2017 году. До появления этих двух фреймворков было несколько других вариантов для разработчиков, таких как Xamarin, Cordova и Ionic, но с тех пор они потеряли популярность из-за множества проблем со сложностью и производительностью. Относительно недавно команда JetBrains (компания, разработавшая несколько популярных IDE) предприняла попытку под названием Kotlin Multiplatform Mobile. Однако он все еще находится в стадии бета-тестирования и не так популярен, как React Native или Flutter.
Если вы новичок в разработке мобильных приложений или еще не работали с какой-либо из этих кроссплатформенных технологий, естественно, возникает вопрос: какую из них следует использовать или потратить свое время на обучение? Моя команда в BrewApps уже много лет разрабатывает мобильные приложения с использованием Flutter и React Native (а также приложений Native), и мы часто размышляли над этим вопросом. В этой статье я попытаюсь выделить некоторые ключевые различия между архитектурами React Native и Flutter, внутренней работой, сильными и слабыми сторонами. Я надеюсь, что это поможет вам или вашей команде разработчиков решить, какую платформу выбрать для вашего следующего проекта по разработке мобильных приложений.
Несмотря на то, что Flutter и React Native предназначены для работы на платформах, отличных от iOS и Android, например, Windows, Linux, macOS, Web и т. д., в этой статье я ограничу обсуждение только iOS и Android.
Какие языки программирования мне нужно выучить?
React Native использует JavaScript, который является широко используемым языком программирования, особенно в мире веб-разработки, поэтому, если вы знакомы с Javascript или React JS, вам будет намного проще понять концепции React Native. С другой стороны, Flutter использует Dart, объектно-ориентированный, типобезопасный, мусорный собранный язык программирования, разработанный людьми из Google. Синтаксис Dart может показаться знакомым из-за его сходства с другими языками программирования, но кривая обучения может быть немного более крутой. Если вы пришли из мира C/C++, вы можете чувствовать себя более комфортно с требованием безопасности типов Dart.
Поскольку JavaScript существует уже довольно давно, он может похвастаться гораздо большим сообществом разработчиков и зрелой экосистемой библиотек, фреймворков и инструментов. С другой стороны, Dart — современный и относительно новый язык программирования, оптимизированный для пользовательского интерфейса. Dart был выбран для Flutter, потому что среда выполнения и компиляторы Dart поддерживают компиляцию на основе JIT, которая позволяет использовать такие функции, как горячая перезагрузка, а также компиляция Ahead-of-Time (AOT), которая генерирует эффективный машинный код, подходящий для производственных развертываний.
Оба языка поддерживают асинхронное программирование, что является ключевым требованием при создании реактивного пользовательского интерфейса в мобильных приложениях. В JavaScript у нас есть async, await и Promises для обеспечения асинхронного выполнения кода, и аналогичным образом в Dart есть ключевые слова async, await и futures. Dart поддерживает параллелизм и параллелизм посредством так называемой изоляции (по сути, абстракции над потоками и процессами). В JavaScript, несмотря на то, что параллелизм достигается с помощью Web Workers для веб-разработки, для React Native вам придется использовать сторонние библиотеки.
n Теперь вы можете задаться вопросом, здесь мы используем JavaScript или Dart, а не Swift и/или Objective-C для iOS и Kotlin и/или Java для Android (используется для разработки нативных приложений); что происходит, когда вы нажимаете кнопку Build или Run? Чтобы понять это, вы можете немного узнать об архитектуре и внутреннем устройстве React Native и Flutter. В большинстве случаев знание этого не является обязательным для разработки приложения React Native или Flutter. Однако более глубокое понимание того, как все работает, может помочь вам принять правильные дизайнерские и архитектурные решения в большом и сложном проекте разработки приложений. Не стесняйтесь пропустить следующий раздел, если в данный момент он вас не интересует.
Что происходит внутри?
React Native
React Native претерпевает серьезные обновления своей архитектуры, и изменения начали вноситься в последние несколько месяцев. О том, что потребовало изменений, мы поговорим чуть позже. Существует множество приложений, все еще использующих старую архитектуру и потенциально находящихся в процессе перехода на новую архитектуру. Поэтому я думаю, что здесь имеет смысл поговорить об обоих.
В старой архитектуре лучший способ понять, как это работает, — представить два мира, JavaScript и Native, и компонент-мост, соединяющий эти миры.
Мост обеспечивает асинхронную двустороннюю связь с использованием сообщений JSON.
Вы, как разработчик React Native, будете писать всю бизнес-логику, обработчики обратных вызовов и т. д. на JavaScript. JavaScript отправляет всю информацию (обычно в виде пакета сообщений) об обновлениях, которые он ожидает отрисовать, на нативную сторону через мост. API-интерфейсы собственной платформы заботятся об отображении представлений. Всякий раз, когда происходит взаимодействие с пользовательским интерфейсом, это событие отправляется на сторону JavaScript, и выполняется соответствующий обработчик. Используя этот механизм моста, React Native по существу имеет доступ ко всем собственным API и, таким образом, контролирует представления базовой платформы (iOS или Android). И что еще более важно, это достигается без необходимости написания собственного кода, т. е. с помощью Objective-C/Swift для iOS и Java/Kotlin для Android.
React Native поставляется в комплекте с оптимизированным для React Native движком JavaScript с открытым исходным кодом под названием Hermes. Виртуальная машина JavaScript запускает код JavaScript в вашем приложении React Native.
Несмотря на то, что мост в старой архитектуре является умным способом облегчения связи между мирами JavaScript и Native, он непреднамеренно становится узким местом из-за практических ограничений пропускной способности моста и влияет на общую производительность в определенных случаях использования. Кроме того, передача сообщений включает операции сериализации и десериализации, которые вызывают задержки обработки, тем самым влияя на взаимодействие с пользователем. Если ваше приложение имеет сложную анимацию с высокой частотой кадров или требует взаимодействия, например быстрой прокрутки, оно может работать не очень гладко в React Native.
Новая архитектура пытается решить эти проблемы, полностью избавляясь от «моста» и вводя новый механизм, называемый интерфейсом JavaScript (JSI). JSI позволяет JavaScript хранить ссылку на хост-объекты и вызывать для них методы и наоборот. Это устраняет накладные расходы на связь (передача сообщений между двумя мирами) и обеспечивает синхронное выполнение и параллелизм.
Новая архитектура, доступная начиная с версии 0.68, построена на том, что команда React Native называет «двумя столпами новой архитектуры».
- Новая система нативных модулей – турбо-модули
Собственные модули позволяют получить доступ к собственному API платформы, который недоступен в JavaScript. Это происходило в старой архитектуре через механизм моста, как описано выше. Turbo Native Modules – это улучшение по сравнению с устаревшими Native Modules, обеспечивающее строго типизированный интерфейс, возможность писать код на C++, отложенную загрузку для более быстрого запуска приложения и использование JSI, как описано выше.
- Новый модуль визуализации — Fabric.
Система рендеринга ткани, написанная на C++, разработана как кроссплатформенная и более совместимая с iOS и Android с целью улучшения взаимодействия с пользователем. Fabric использует отложенную загрузку, JSI и другие преимущества новой архитектуры.
Что происходит, когда вы запускаете приложение React Native?
Когда вы запускаете приложение React Native, базовая операционная система создает и назначает вашему приложению собственный поток, также известный как основной поток или поток пользовательского интерфейса. Затем собственный поток настраивает собственную инфраструктуру и порождает виртуальную машину JavaScript, которая запускает код JavaScript (вашего приложения и фреймворка). Затем поток Native запрашивает поток JavaScript обработать основной компонент, который зарегистрирован как точка входа в AppRegistry, после чего начинается взаимодействие между JavaScript и миром Native. То, что я описал, слишком упрощено для целей этой статьи, но если вам интересно узнать больше о мельчайших подробностях, взгляните на этот превосходный запись в блоге. р>
Флаттер
Архитектура Flutter сильно отличается от архитектуры React Native. Вот графическое представление многоуровневой архитектуры Flutter.
Как разработчик приложений Flutter, вы потратите большую часть своего времени на первые два уровня, написав бизнес-логику вашего приложения в Dart и используя библиотеки и сервисы, доступные на уровне фреймворка.
Во Flutter сказано: «Все — это виджет», что, по сути, означает, что вы строите свой экран пользовательского интерфейса из виджетов. Flutter предоставляет обширный набор базовых виджетов. Каждый аспект пользовательского интерфейса описывается как виджет, а виджеты вложены друг в друга для построения дерева виджетов. Слой ниже, движок Flutter (написанный на C++), в основном отвечает за низкоуровневые примитивы ввода/вывода и перевод всех описаний пользовательского интерфейса в реальные пиксели (т.н. растеризация). Это достигается за счет использования графического движка Skia. Таким образом, вместо того, чтобы полагаться на виджеты, предоставляемые платформой, Flutter использует свой собственный высокопроизводительный механизм рендеринга для рисования «виджетов Flutter». операционная система и флаттер. Средство встраивания координирует свои действия с базовой операционной системой для доступа к таким службам, как поверхности рендеринга, ввод и т. д. Для каждой целевой платформы будет отдельный модуль внедрения, например, по одному для iOS и Android.
Что происходит, когда вы запускаете приложение Flutter?
Когда вы запускаете приложение Flutter, компонент встраивания, который мы обсуждали ранее, предоставляет точку входа и инициализирует механизм Flutter. Механизм Flutter отвечает за управление виртуальной машиной Dart и средой выполнения Flutter. Рендеринг, ввод, обработка событий и т. д. затем делегируются скомпилированному коду Flutter и приложения.
В дополнение к этим основным различиям в архитектуре между Flutter и React Native, здесь важно отметить, что код Dart предварительно компилируется в собственные библиотеки, библиотеки ARM или x86 при развертывании в рабочей среде. Затем библиотека упаковывается как проект «бегун», и все это встраивается в файл .apk или .ipa. Кроме того, в отличие от React Native, Flutter использует не встроенные виджеты платформы, а виджеты из собственной библиотеки (виджеты Material Design или Cupertino), которые управляются и отображаются с помощью платформы и движка Flutter.
Что делать, если мне нужно что-то, предлагаемое платформами (iOS или Android), но не представленное во Flutter или React Native?
В React Native с устаревшей архитектурой вы можете писать модули Native для доступа к API платформы, которые недоступны в JavaScript. Модули Native могут быть созданы внутри вашего проекта React Native или отдельно в виде пакета NPM. В новой архитектуре устаревший модуль Native заменяется модулем Turbo Native и собственными компонентами Fabric.
С Flutter вы можете писать пакеты плагинов для Android (на Kotlin или Java) и iOS (на Swift или Objective-C). В дополнение к этому, вы также можете написать код для конкретной платформы в своем приложении и сделать так, чтобы часть вашего приложения Dart взаимодействовала с частью, не относящейся к Dart, используя так называемый канал платформы. Это сообщение, передаваемое между Dart и другой частью, аналогично передаче сообщения через мост в React Native.
Инструменты для отладки и разработки
React Native и Flutter имеют множество функций и инструментов разработчика для отладки и мониторинга производительности.
И React Native, и Flutter поддерживают «горячую перезагрузку», что, по сути, означает, что когда вы запускаете приложение в режиме отладки на симуляторе, любое изменение, которое вы вносите в код, почти мгновенно отражается в окне вашего симулятора. Это очень удобно, так как вам не нужно каждый раз перекомпилировать все приложение (и ждать его завершения), вам нужно проверить, как незначительные изменения в вашем коде повлияют на пользовательский интерфейс или функциональность. В React Native функция горячей перезагрузки называется «Быстрое обновление». Горячая перезагрузка во Flutter возможна благодаря способности Dart использовать свою виртуальную машину для JIT-компиляции кода.
В React Native вы можете использовать отладчик JavaScript в инструментах разработчика браузера Chrome для отладки кода JavaScript, настроив удаленную отладку вашего проекта. Отладку собственного кода можно выполнить, запустив приложение в Android Studio или Xcode и используя доступные собственные функции отладки в среде IDE. Некоторым разработчикам такая установка кажется немного неуклюжей.
Flutter поставляется с обширным набором инструментов для повышения производительности и отладки. Эти пакеты и инструменты можно установить напрямую в популярные IDE, такие как IntelliJ, VS code и т. д.
n Что сообщество разработчиков говорит о Flutter и React Native?
Давайте посмотрим на некоторые опросы разработчиков Stack Overflow за последние два года.
На вопрос о том, над какими фреймворками и библиотеками вы активно работали в прошлом году и над какими хотите поработать в следующем году?
2021
2022
На вопрос о том, какие технологии они изучали в 2022 году
Эти опросы показывают, что интерес разработчиков как к React Native, так и к Flutter остается высоким, а в последнее время наблюдается небольшой рост интереса к Flutter. Тенденции Google за последний год подтверждают это.
Какие компании используют React Native или Flutter для разработки своих мобильных приложений?
Список компаний, использующих эти кроссплатформенные технологии, постоянно растет. Вот несколько важных упоминаний:
| React Native | Флаттер | |----|----| | Фейсбук | БМВ | | Shopify | Нубанк | | Викс | Google Play | | Тесла | Мечта11 | | Флипкарт | Тойота |
Я убежден, что React Native и Flutter — это будущее разработки мобильных приложений. С чего начать?
Официальная документация по React Native и Flutter — отличный ресурс для обучения и настройки для разработки вашего первого кроссплатформенного мобильного приложения.
Ниже приведены несколько других ресурсов среди многих других, которые содержат хороший контент для обучения и начала работы.
- Популярный курс Udemy по React Native от Максимилиана
- Еще один курс Udemy от Стивен Грайдер< /сильный>
- Учебники по Flutter на странице Codewithandrea .
- Основы Flutter Учебные пособия и видео Рэя Вендерлиха
- Видео YouTube о разработке Flutter, автор Маркус Нг
Окончательный вердикт
Оба фреймворка имеют свои сильные и слабые стороны, поддерживаются такими крупными компаниями, как Google и Facebook, имеют процветающее сообщество разработчиков и останутся с нами надолго. Глядя на опросы разработчиков и основываясь на нашем собственном опыте создания приложений с использованием обеих этих технологий, кажется, что на данный момент Flutter имеет небольшое преимущество перед React Native из-за его богатой библиотеки виджетов, удобных для разработчиков инструментов и общей производительности. Однако это сводится к вашим конкретным требованиям к приложению, доступности ресурсов, а также опыту и предпочтениям команды разработчиков. Мы надеемся, что эта статья поможет вам оценить это и принять правильное решение.
Оригинал