Блог Hunterprice Digital

Flutter vs React Native. Вторая Битва титанов. Разбираемся на чем построить ваш проект.

Время прочтения: 10 минут


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

Мы провели с Flutter несколько месяцев на проекте, и теперь поделимся опытом, сравнив его с React-Native, с которым у многих довольно богатый опыт.

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

Обычно у вас есть 3 варианта мобильного приложения:
  • полностью родное с Kotlin / Swift,
  • полностью веб-приложение (PWA или контейнер WebView) и
  • cross platform Native (поскольку это не веб-приложения, а Native Apps, которые тем не менее используют кроссплатформенный подход).

Обе технологии предоставляют схожие возможности, однако использовать Flutter немного рискованно сейчас из-за его незрелости, недостатка библиотек и не очень большого пока ещё сообщества.

Итак погнали.

Критерии оценки
Мы не будем углубляться в суть технологий, а лучше оценим их с точки зрения применения в проектах и их возможностей в целом и рассмотрим по следующим аспектам:
  • Сборка и развертывание.
  • Доступность библиотек и виджетов.
  • Инструменты и тестирование.
  • Производительность.
  • Опыт разработчиков.
  • Возможности сети.
  • Возможности медиа.
  • Безопасность.


1️⃣ СБОРКА И РАЗВЕРТЫВАНИЕ
Обе технологии — кроссплатформенные и используют один и тот же подход: у них есть собственные части для Android и iOS, и включают кроссплатформенные среды выполнения, будь то JavaScript или Dart. Это можно представить следующим образом:


Обе платформы используют инструменты мобильной операционной системы для сборки: Gradle и Xcode build для Android и iOS соответственно. В этом плане разницы между ними и нативными приложениями нет.

Хотя есть разница в скорости сборки. Это не так важно для разработки, однако критично во время сборки CI и архивирования приложения в Xcode. У нас нет точных цифр, но приложение «Hello, World» на Flutter собирается мерно в 3 раза быстрее, чем в React Native. Причина в том, что Flutter поставляется как iOS Framework, а React Native перекомпилируется из исходников.

Здесь будет абсолютно справедливо дать каждой технологии по баллу.
Flutter vs React Native: 1 -1 


2️⃣ УПРАВЛЕНИЕ ЗАВИСИМОСТЯМИ
👍 React Native использует пакеты NPM для включения зависимостей приложения, включая сам React Native. Помимо NPM, можно использовать Yarn для установки и управления своими зависимостями. Зависимости, которые требуют кода Kotlin / Java / Swift / Objective-C, связываются с помощью модулей gradle и пакетов CocoaPods. React Native включает функцию автоматической линковки, которая позволяет избежать ручного изменения файлов gradle и Podfile.

👍 Flutter, в свою очередь, использует менеджер пакетов dart, также известный как инструмент pub. Пакеты поставляются в виде исходного кода и компилируются вместе с основным приложением. Как и в RN, эти пакеты могут иметь собственные зависимости, но в этом случае может потребоваться вручную добавить эти зависимости в файлы gradle и Podspec, хотя на практике лично мы с этим не сталкивались. Можно также использовать неопубликованные пакеты, забирая их из папки или git репозитория.

Здесь оба получают опять по баллу точно.
Flutter vs React Native: 2 -2 


3️⃣ ПУБЛИКАЦИЯ
Описанная выше архитектура означает, что необходимо преобразовать или скомпилировать общий код, включить его в окончательный apk / ipa и отправить результат в магазин приложений. Процесс может выглядеть следующим образом:


Однако между RN и Flutter всё же есть различия.
React Native поддерживает технологию Code Push, позволяющую отправлять обновления кода JS без повторной публикации apk / ipa из-за того, что React Native запускает пакет кода JS во время выполнения и может его заменить.

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

Думаем здесь Flutter нужно накинуть балл сверху.
Flutter vs React Native: 3 - 2 


4️⃣ НАЛИЧИЕ БИБЛИОТЕК И ВИДЖЕТОВ
Библиотеки и компоненты сторонних сторон
👍 React Native присутствует на рынке уже более 6 лет и располагает тоннами библиотек для различных случаев, начиная с push-уведомлений, воспроизведения видео и компонентов материалов, заканчивая камерой (включая Firebase ML Kit) и интеграциями Apple HealthKit и Google Fit. Существует тщательно подобранный список высококачественных сторонних компонентов, которые можно использовать в своем приложении, под названием awesome-react-native.

👍 React Native также сильно выигрывает от того, что он основан на React и имеет возможность использовать библиотеки, созданные для React, например Redux или axios, или привносить современные функции, такие как React Hooks.

👎 Flutter существует всего 2,5 года, тем не менее он становится все популярнее с каждым днем, что безусловно мотивирует энтузиастов разрабатывать для него библиотеки. Уже существуют некоторые решения для навигации, слайдеры, компоненты пользовательского интерфейса, интеграции Firebase и так далее. Однако многие возможности все еще находятся на базовой стадии. Существует также тщательно подобранный список библиотек для флаттера, который называется awesome-flutter. Можно заметить, что этот список в 3 раза меньше, чем у RN. Конечно, это не показатель, но это дает представление о перспективе развития технологии.
Кроме того, Dart редко используется вне Flutter, а сам Flutter не основан на какой-либо другой библиотеке фреймворка, что также не помогает с готовыми к использованию компонентами или подходами.

Виджеты
👍 React-Native имеет большую библиотеку компонентов пользовательского интерфейса: календари, средства выбора даты, кнопки, компоненты материалов, поддержку SVG и многое другое.

👎 Flutter поставляется с компонентами Material и Cupertino из коробки. Но вот библиотека пользовательского интерфейса находится на ранней стадии. Возможно, с недостатком компонентов вы и не столкнетесь, однако количество библиотек компонентов для React Native намного больше. Это изменится в ближайшем будущем, поскольку все больше и больше разработчиков  начинают работать с Flutters.

Здесь же точно RN берет балл, без вопросов.
Flutter vs React Native: 3 - 3 


5️⃣ ИНСТРУМЕНТЫ И ТЕСТИРОВАНИЕ
Оба стека включают:
  • Инструменты стиля и качества кода (eslint, tslint, prettier vs dartanalyzer).
  • Unit-тесты (с Jest-тестом и Flutter-тестом).
  • Тесты компонентов (снимки, Enzyme-тесты и виджет-тесты, «золотые тесты»).
  • e2e тестирование (Detox vs e2e).

Мне кажется, что в этом обе примерно технологии равны. 
Flutter vs React Native: 4 - 4 


6️⃣ ПРОИЗВОДИТЕЛЬНОСТЬ
Производительность следует рассматривать с нескольких точек зрения:
  • Производительность рендеринга;
  • Время запуска.

Производительность рендеринга
👎 React Native использует родные виджеты платформы(Native Views) и передает события через JavaScript. Это влияет на производительность уровня представления, однако 60 fps в секунду все еще достижимы, хотя производительность зависит от версии ОС и самого устройства.

👍 Flutter, с другой стороны, рендерит все, используя собственный 2D-движок Skia, избегая какого-либо специального соединения между вьюшками и другим кодом. Это делает рендеринг невероятно быстрым. У него могут быть проблемы с iOS, но эта проблема должна быть решена с помощью недавней поддержки Metal.

Время запуска
👎 У React Native есть проблема с этим. Вообще, время запуска — это распространенная проблема, если вы стремитесь к совершенству своего мобильного приложения. RN должен загрузить виртуальную машину JS, а затем JS код. На Android это становится сложной задачей. Версия React-Native 0.60 обеспечивает поддержку Hermes: новой экспериментальной виртуальной машины JS для Android, которая предназначена для быстрой загрузки.

👍 Flutter, кажется, уже решил эту проблему.

Здесь опять ноздря в ноздрю.
Flutter vs React Native: 5 - 5 


7️⃣ ОПЫТ РАЗРАБОТЧИКА (DX, Developer Experience)
👎 У React Native есть функция Fast Refresh, которая позволяет мгновенно видеть изменения на симуляторе / эмуляторе или реальном устройстве, это сокращает цикл обратной связи практически до нуля, в отличие от нативной разработки. Разработка обычно выполняется с помощью VSCode или WebStorm (это самые популярные инструменты). Оба включают в себя возможности для запуска и отладки кода, запуска тестов, просмотра покрытия и обеспечения автозаполнения. На наш взгляд у RN автозаполнение ограничено (я думаю, из-за JavaScript), поэтому мы вернулись к запуску сборки либо с npx react-native run-ios или через Xcode, потому что запуск через WebStorm был очень нестабильным. Также время от времени падал сам упаковщик. Типичный способ отладки — это запуск Google Chrome и использование его консоли, что является неоптимальным

👍 У Flutter отличный DX. Поскольку это продукт Google, он позволяет интегрировать IDE (Android Studio, но я предпочитаю IntelliJ Idea как более стабильную) сразу с набором инструментов. Быстрая загрузка почти такая же, как и быстрое обновление, и даже лучше. Автозаполнение работает на ура, поскольку Dart строго статический и типизированный, что создает поддержку стабильности среды разработки IDE. Тут надо сделать замечание, что Dart из коробки предоставляет большую свободу в плане типов, вы можете их вообще не писать, поэтому рекомендуется его донастроить в своем проекте.
Кроме того Flutter показывает причины ошибок, поэтому их легко пофиксить. Отладчик в IDE тоже работает очень хорошо. VSCode также поддерживает Flutter, но не имеет функций отладки и VCS.

Победный балл за Flutter.
Flutter vs React Native: 6 - 5 



8️⃣ СЕТЕВЫЕ ВОЗМОЖНОСТИ
👍 React Native работает с базовым протоколом http(s) с полифилом fetch, встроенной поддержкой WebSockets и богатые клиенты с axios (еще один пример чистой библиотеки js!) и rn-fetch-blob. React Native также парсит json из коробки, потому что это тоже JavaScript. Это также означает, что можно создавать свои типы с помощью Open Api.

👎 У Flutter есть только встроенные клиенты http (s) и WebSockets. Клиент Axios находится в стадии разработки (я даже думаю о создании собственного, скажем, «fluxios»)). Парсинг JSON(конечно, если вы не используете кодогенерацию) нужно производить вручную. Поддержка открытого API существует, но она не обновлялась 15 месяцев. Существуют пакеты Dio и Chopper для упрощения работы с http, и скорее всего, появятся еще.
К сожалению, как оказалось, использование кодогенерации для openapi для Dart вызывает определенные проблемы.

И опять RN выигрывает этот раунд. Паритет.
Flutter vs React Native: 6 - 6 


9️⃣ МЕДИАВОЗМОЖНОСТИ
Обе технологии сильно зависят от базовых платформ. Никакие фреймворки для Android / iOS сами по себе ничего не делают в плане медиа, а скорее используют медиакомпоненты, доступные в системе. Вопрос лишь в том, насколько хорошо поддерживаются возможности платформы.

👍 React Native поддерживает воспроизведение и запись как аудио, так и видео. Можно, например, показывать видео в разных форматах (в основном все они поддерживаются ExoPlayer (Android) и AVPlayer (iOS)), отображать элементы управления для поиска, зацикливания и т.д. Также можно отображать субтитры SRT и VTT для видео «из коробки». Этот функционал поставляется с такими компонентами, как react-native-video, react-native-video-controls и другими.

👎 В основном Flutter имеет только пакет video_player для воспроизведения видео. Его версия 1.0 все еще находится на рассмотрении и может отображать все видеоформаты, предоставляемые мобильными ОС, а вот субтитры — только SRT, субтитры VTT отсутствуют в дорожной карте. VTT субтитры тем не менее поддерживается отдельным пакетом. Для основных элементов управления необходимо использовать пакет Chewie.

Здесь победа за RN.
Flutter vs React Native: 6 - 7 


🔟 БЕЗОПАСНОСТЬ
👎 React Native завязан на js и приложение на его основе содержит js bundle. Но его всегда можно извлечь и понять логику приложения, или изменить ее. Похоже, это серьезная проблема.

👍 С Flutter гораздо сложнее изменить приложение, так как Dart код заранее компилируется в бинарный код для целевой архитектуры.

Здесь полная победа Flutter точно.
Flutter vs React Native: 7 - 7 

Резюмируем:
Как всегда, выбор зависит от нефункциональных требований, но мы бы рекомендовали при этом учитывать:
  • Недостаток библиотек для Flutter.
  • Обучение Dart новым разработчикам, так как таких разработчиков на рынке нет/мало.
  • Неполные медиа возможности для Flutter.
  • Более длительное время запуска React-Native.
  • Более низкая безопасность для React-Native.

И конечно итог битвы: 7 - 7. Пока ничья на сегодняшний день.