В среде разработчиков все чаще сопоставляются Flutter и React Native. Оба популярных инструмента являются мультиплатформенными, оба способны быстро и легко создавать мобильные приложения.
Тем не менее, вопрос: “Что выбрать — Flutter или React Native?” вызывает у специалистов оживленные споры.
Попробуем ответить на этот вопрос честно и некатегорично. В конце концов, выбор платформы является лишь одним из многих факторов успеха приложений.
В начале разговора напомню, что я разработчик Flutter. Думаю, это важно уточнить, хотя данная статья была согласована с обеими нашими инженерными командами — — как Flutter, так и React Native.
Важно также отметить, что мы, специалисты Stream, имеем опыт использования обоих фреймворков. У нас есть специальные команды для каждого пакета Chat Messing SDK. В этом преимущество Stream для широкого сообщества разработчиков: команды могут выбрать ту платформу, которую считают более подходящей для обеспечения беспрепятственного общения в чате.
Поэтому предлагаю рассмотреть оба фреймворка, чтобы выяснить, чем же они отличаются и как каждый из них можно использовать в разных целях разными командами разработчиков.
Опыт разработчиков
Опыт разработчиков (от англ. термина “developer experience”) — это общее мнение профессиональных разработчиков и опытных пользователей, составленное на основе применения библиотеки. Все, начиная с документации и заканчивая фактическим представлением API библиотеки, формирует опыт разработчиков. Вот почему он часто становится решающим фактором при вынесении командой вердикта по поводу нового SDK для приложения.
Что касается Flutter, то разработчики и компании могут легко анализировать количественные данные, чтобы оценить общее мнение сообщества и удовлетворенность SDK. Дело в том, что команда Google отправляет разработчикам Flutter ежеквартальные исследования, а затем публикует обширный отчет с подробным описанием их результатов.
Одним из показателей, который выделяется в последнем отчете Flutter за 2-й квартал, является уровень удовлетворенности библиотекой. В конце 2-го квартала уровень удовлетворенности в базе пользователей Flutter достиг 92 %. Его можно объяснить несколькими ключевыми вещами, которые являются сильными сторонами фреймворка. Перечислим их.
Документация и образцы API
Команда по связям и сообщество Flutter проделали огромную работу по документированию интерфейсов платформы и общих шаблонов. Их недавняя кампания по стимулированию разработчиков “прими” виджет не только открыла двери внешнему содействию, но и привела к появлению десятков примеров кода для популярных виджетов Flutter.
Инструментарий разработчика
Инструментарий разработчика — неотъемлемая часть взаимодействия с Flutter. Платформа приложила массу усилий для создания инструментальных средств разработчика и инвестирования в них. DevTools от Flutter — это интерактивный набор инструментов для повышения производительности и отладки, которые позволяют разработчикам напрямую взаимодействовать со своей средой IDE из Chrome. Использование Flutter DevTools — это, прежде всего, возможность интерактивной настройки макетов и быстрого устранения часто возникающих с ними проблем.
Пакеты сторонних разработчиков
У Flutter и Dart есть система управления пакетами под названием Pub. Она позволяет разработчикам загружать, просматривать и использовать пакеты, созданные сообществом. Пакеты в Pub могут варьироваться от виджетов Flutter до чистых библиотек Dart, таких как http и crypto. Команда Flutter вместе с сообществом делает обзоры популярных пакетов под меткой “Flutter Favorites” (“Избранное Flutter”). Это позволяет разработчикам-новичкам быстро находить высококачественные (и надежные) библиотеки для своих проектов.
С точки зрения опыта разработчиков, платформа React Native в чем-то похожа на Flutter. Команда Facebook проделала огромную работу, разместив информацию на странице гайда React Native ”Приступая к работе”. Эта страница отправляет разработчиков на экскурсию с гидом по фреймворку.
Хотя я не смог найти никаких официальных пользовательских исследований по React Native, стоит отметить, что React Native существует гораздо дольше, чем Flutter. Этот фреймворк имеет более значительное сообщество последователей по сравнению с Flutter.
Количество пакетов и плагинов React Native значительно превышает количество пакетов и плагинов Flutter, поскольку разработчики могут использовать большинство библиотек JS и пакетов React.
Что касается инструментария, у разработчиков React Native тут больше возможностей, чем у их коллег из Flutter. Благодаря своей зрелости и способности использовать цепочки инструментов JS, React Native предоставляет больший выбор стандартных инструментальных средств JS для оптимизации рабочего процесса. Некоторые из них включают среды IDE, такие как VSCode, для пакетов по проверке качества кода, таких как ESLint.
Flutter отличается от React Native специализированным набором инструментов Flutter DevTools. Он позволяет разработчикам быстро отлаживать очень сложные проблемы с макетами, производительностью и сетью без установки дополнительных инструментов. Приложения React Native, помимо стандартного инструментария React Developer Tools, теперь поддерживаются Flipper — расширяемым отладчиком мобильных приложений.
Чтобы узнать больше об инструментах React Native, ознакомьтесь с постом в Instabug, посвященным этой теме.
Таким образом, опыт разработчиков обеих платформ соответствует требованиям к фреймворку 2021 года. У каждой из них отличная документация (здесь у Flutter есть небольшое преимущество) с подробными руководствами и инструментами разработчика.
Производительность труда разработчиков
Производительность труда разработчиков (от англ. термина “developer productivity”) — тема, вызывающая наибольший интерес в сообществе. Хочу предварить ее одним замечанием: некоторые из приведенных здесь разделов полностью зависят от личных предпочтений. Каждый разработчик индивидуален, и каждый предпочитает свой собственный рабочий процесс и инструментарий.
Чтобы оценить производительность труда разработчиков, рассмотрим следующие аспекты каждой платформы:
- Выбор языка;
- Экосистема разработки (пакеты и плагины).
Выбор языка
Начнем, пожалуй, с самого обсуждаемого аспекта: выбор языка. Он оказывает волновой эффект на весь фреймворк. От выбора языка зависит не только производительность труда разработчиков, но и производительность всего фреймворка — подробнее обсудим это позже.
React Native
React Native в качестве предпочтительного языка использует JavaScript (JS). Сам фреймворк основан на популярном проекте ReactJS. В результате React Native приобрел большую популярность среди разработчиков. Если вы когда-либо создавали веб-приложение с помощью React, то наверняка убедились в том, что переход к написанию первого приложения React Native чрезвычайно прост.
Структура кода React Native в основном сильно напоминает структуру кода React. Возможно, вам даже удавалось повторить логику React-проектов в проектах React Native.
Хотя JS позволяет разработчикам использовать в своих веб-приложениях огромное количество проектов и библиотек, у этого языка есть серьезные недостатки.
Начнем с того, что JS — динамический язык (если вы не решите использовать Typescript, который дополнен статической типизацией). Это означает, что в JS-логике нет системы звуковых типов или нулевой безопасности.
Если вы занимались разработкой нативных приложений и использовали React Native как свой первый кроссплатформенный фреймворк, отсутствие сильной типизации и предупреждений анализатора могло поначалу шокировать вас. Хотя такие инструменты, как ESLint, помогают уменьшить количество очевидных ошибок в коде, не исключены ситуации, когда происходит нечто неожиданное, обнаруживаемое только во время выполнения.
Поскольку JS не может компилироваться в нативный машинный код, весь код, написанный как часть приложения React Native, должен быть скомпилирован на пользовательском устройстве с помощью виртуальной машины JS.
Я не говорю, что динамические языки ужасны. Некоторые разработчики предпочитают использовать JS из-за его гибкости и низкого порога входа. Однако важно отметить, что при работе с более крупными приложениями вы будете подвержены ошибкам, которые чрезвычайно редки в нативном или сильно типизированном мире МО.
Flutter
Flutter в мире фреймворков занимает уникальное положение. Dart — язык, используемый Flutter для написания большей части стека, — поддерживается как Google, так и командой Flutter (Примечательно, что команды Dart и Flutter имеют одного и того же менеджера по продукции).
Это означает, что команда может оптимизировать фреймворк (Flutter) и язык (Dart), чтобы повысить эффективность процесса разработки. Наглядным примером тому можно считать недавнее добавление condition-литералов и spread-оператора. Оба эти небольшие дополнения к языку сделали его в значительной степени более полезным для разработчиков, создающих приложения с помощью Flutter.
С точки зрения самого языка, Dart можно описать как обладающий синтаксисом в c-стиле, который хорошо знаком разработчикам, использовавшим JS, C# или Java.
В отличие от JS, Dart статически типизирован и недавно был обновлен, чтобы обеспечить звуковую нулевую безопасность. Современный код Dart теперь по умолчанию не допускает неопределенного значения. Это означает, что компилятор может предупредить вас о потенциальных ошибках разыменования нулевого указателя до их возникновения.
Стоит также упомянуть, что Dart может компилироваться в двух режимах: JIT (“Точно в срок”) и AOT (“Досрочно”). Это позволяет разработчикам извлекать выгоду из быстрого итеративного цикла разработки в режиме JIT, а также создавать небольшие и производительные пользовательские приложения, скомпилированные в режиме AOT. Язык может компилироваться в машинный код как на десктопных, так и на мобильных устройствах, поэтому при работе над производственными приложениями нет необходимости в виртуальной машине.
Хотя в распоряжении Flutter нет большой коллекции пакетов с открытым исходным кодом (в отличие от JS), он компенсирует этот недостаток высокой производительностью. Хорошо написанное приложение на Flutter в рабочем режиме может функционировать со скоростью 60–120 кадров в секунду.
Кроме того, разработчики могут загружать большие вычислительные задачи, такие как декодирование или сортировка JSON, в фоновые изоляты (версия потоков Flutter/Dart), чтобы поддерживать производительность и избегать блокировки пользовательского интерфейса.
Экосистема разработки
Ключевым моментом продажи любого SDK или фреймворка является сформированная вокруг него система инструментальных средств поддержки. Оба SDK характеризуются обширной и продуманной экосистемой, располагающей к открытому исходному коду.
React Native имеет большое преимущество, предоставляя разработчикам возможность использовать в своих приложениях большинство библиотек JS с открытым исходным кодом. В результате разработчики могут перейти к своему любимому менеджеру пакетов (на ум сразу приходит npmjs), найти пакет JS, который решает задачи необходимого варианта использования, и легко добавить его в свое приложение.
Flutter также обладает полезными объектами с открытым исходным кодом. Но впечатление от них меркнет в сравнении с огромным количеством пакетов, из которых могут выбирать разработчики React Native.
Например, согласно libraries.io, общее количество пакетов в Pub в настоящее время составляет 24 952, в то время как количество пакетов в npm достигает 1,98 млн.
Широкий спектр проектов обеих платформ можно нередко найти на NPM и Pub.dev. Чтобы помочь разработчикам выбрать нужный пакет для своего проекта и придать им уверенности, команда Flutter запустила программу “Избранное Flutter” с обзором наиболее часто используемых пакетов.
Хотя NPM является самым популярным источником пакетов JS, стоит отметить, что не все пакеты в NPM поддерживают React Native. React Native Directory — веб-сайт, посвященный размещению библиотек React Native, — в настоящее время содержит 982 библиотеки.
Эффективность
Очевидный факт заключается в том, что раньше существовал заметный разрыв в эффективности между Flutter и React Native. С годами он сократился. Сегодня у Flutter все еще остается небольшое преимущество перед React Native, но для большинства приложений оно незначительно.
Хотя реклама обоих фреймворков убеждает в том, что оба они являются “по-настоящему нативными” приложениями, это не совсем так.
Эффективность React Native
Пользовательский интерфейс приложений React Native состоит из нативных компонентов Android и iOS. Это означает, что вы используете виджеты платформы, которые поставляются с каждой версией операционной системы.
Когда разработчик использует текст для отображения информации в своем приложении, с точки зрения внутренней структуры React Native отображает TextView
на Android иUITextView
на iOS. У этого подхода, безусловно, есть свои плюсы, поскольку UI всегда знаком конечному пользователю и является нативным для каждого устройства.
Однако написанные на JS код и бизнес-логика впоследствии приходится выполнять на устройстве с использованием виртуальной машины JS и моста. Многие разработчики недовольны этой настройкой React Native.
Не вдаваясь в лишние подробности, отметим: подобный тип архитектуры означает, что для обновления UI или изменения определенных частей приложения написанный JS-код необходимо не только интерпретировать, но и добавить в очередь, чтобы он мог пересечь мост фреймворка для взаимодействия с нативными модулями.
Казалось бы, незначительный недостаток; но на самом деле все с точностью до наоборот. Команда Facebook усердно работает над обновлением архитектуры React Native, чтобы решить изложенные выше проблемы, включая депрекацию моста. Основные усилия направляются на внедрение JSI — механизма, который обеспечит прямую связь между потоком JS React Native и нативными модулями.
Если вам интересно, прочитайте больше о ”реструктурировании” React Native.
Эффективность Flutter
В мире Flutter все обстоит совсем по-другому. В отличие от React Native, Flutter не полагается на нативные компоненты или представления. Вместо этого, Flutter рисует каждый пиксель на экране, предоставляя разработчикам полный контроль над циклами рисования и макетирования. Возможно, вам было бы проще представить себе Flutter как игровой движок, но только предназначенный для создания приложений.
Фреймворк состоит из пяти отдельных слоев:
- Material и Cupertino: Библиотеки Material и Cupertino предлагают комплексные наборы элементов управления, которые используют примитивы композиции слоя виджета для реализации языков дизайна Material или iOS.
- Виджеты: Слой виджетов — это абстракция композиции. Каждый объект визуализации в слое визуализации имеет соответствующий класс в слое виджетов. Кроме того, слой виджетов позволяет определять комбинации классов, которые можно использовать повторно. Это уровень, на котором вводится модель реактивного программирования.
- Рендеринг: Слой рендеринга обеспечивает абстракцию для работы с макетом. С помощью этого слоя можно построить дерево визуализируемых объектов. Вы можете управлять этими объектами динамически, при этом дерево автоматически обновляет макет, чтобы отразить ваши изменения.
- Dart UI: Основополагающие классы и сервисы конструкционных блоков, такие как анимация, рисование и жесты, которые предлагают обычно используемые абстракции помимо основополагающих структур.
Чтобы оживить свои приложения, разработчики используют агрессивную композицию с применением виджетов из каждого слоя.
Результатом компиляции такого кода является быстрое и отзывчивое приложение. Поскольку Flutter использует Dart в качестве языка, приложения могут быть скомпилированы непосредственно в нативный машинный код. Это означает, что в рабочей среде нет необходимости в виртуальной машине или мосте. Кроме того, разработчики Flutter также могут воспользоваться интерфейсом внешней функции (FFI) для быстрого и эффективного взаимодействия с кодом C (или любым другим совместимым языком) в своих приложениях.
Flutter не требует моста в рабочей среде для отображения пользовательского интерфейса, но ему нужен мост для взаимодействия с базовой платформой и плагинами (например, с плагином Google maps).
Вообще говоря, скомпилированное приложение Flutter обычно меньше и быстрее, чем скомпилированное приложение React Native; однако в конечном счете все определяется сложностью приложения и выбором зависимостей.
Сообщество
Заключительная и важнейшая часть выбора фреймворка — это сообщество его разработчиков. Вы неизбежно столкнетесь с проблемами, которые не сможете решить самостоятельно, и наличие сообщества людей, которые знают, как справиться с подобными проблемами, является главным плюсом.
Обе платформы прошли долгий путь с момента своего появления, и сегодня обе можно считать зрелыми экосистемами.
Если вы уверенный пользователь Twitter, то вам не составит труда найти группы разработчиков от обеих платформ, увлеченных своим делом и способных оказать действенную помощь. Flutter Community и React Native Community являются примерами отличных Twitter-аккаунтов, которые готовы делиться своими ресурсами с разработчикам-новичками.
В дополнение к этому, Flutterista и ReactJSGirls предоставляют комфортное пространство для женщин, желающих поделиться своим опытом взаимодействия с Flutter и React Native.
Такие веб-сайты, как Stack Overflow и Medium, также содержат большое количество контента о Flutter и React Native, охватывающего широкий спектр технических и нетехнических аспектов каждой платформы.
Перспективы
Будущее обеих платформ представляется довольно светлым. С изменением архитектуры React Native и внедрением JSI команда Facebook вдохнет новую жизнь в фреймворк, который, как некоторые полагают, находился в состоянии медленного угасания.
Недавно команда React Native опубликовала пост в блоге, в котором сообщила о своем намерении выйти за рамки мобильных устройств и войти в десктоп-пространство. Лично я очень рад этому. Здорово видеть, как все больше фреймворков разветвляются и пробуют что-то новое.
Команда Google проделывает фантастическую работу по совершенствованию Flutter, прислушиваясь к сообществу и внедряя функции, которые действительно расширяют возможности разработки Flutter. Недавнее добавление нулевой безопасности и запуск обходных решений для классов данных в Dart являются наглядными примерами этой работы.
На прошлой неделе вышла новая — основная — версия Flutter 2.5. Она порадует разработчиков устранением некоторых распространенных ошибок и недавних проблем с производительностью. Для получения дополнительной информации об этом выпуске ознакомьтесь с Новыми возможностями Flutter 2.5.
Сегодня на дворе 2021 год, и мы знаем: мир не черно-белый. Для нас в порядке вещей выбирать одну из сторон в дебатах о мобильных приложениях и утверждать, что один фреймворк лучше другого. Однако, если вы надеялись, что эта статья закончится объявлением “победителя”, вынужден вас разочаровать: в реальной жизни почти никогда не бывает победителей и побежденных.
Поэтому, будь вы разработчиком или компанией, которая хочет создать мобильное приложение, задайте себе следующие вопросы:
- Каково предназначение вашего приложения?
- Каковы сильные стороны вашей команды?
- Планируете ли вы использовать один код для различных проектов?
- Что вы создаете: мобильное приложение или веб-приложение с мобильным клиентом?
В конечном счете все зависит от вашего проекта и доступных вам ресурсов. Все разработчики или команды находятся в разных условиях.
Читайте также:
- Как тестировать компоненты React
- Комплексная разработка веб-приложений с помощью React и Node.js
- Как использовать библиотеку веб-компонентов React от Uber
Читайте нас в Telegram, VK и Дзен
Перевод статьи Nash: Flutter vs. React Native: The Ultimate Comparison for Your Next Project