Flutter vs React-Native: детальное сравнение

0
0
views

Перевод статьи «Flutter vs React-Native: comparison in depth», выполненный Владимиром Ивановым, Solution Architect в EPAM, и опубликованный сайтом tproger.ru.

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

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

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

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

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

Критерии оценки

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

  • Сборка и развертывание.
  • Доступность библиотек и виджетов.
  • Инструменты и тестирование.
  • Производительность.
  • Опыт разработчиков.
  • Возможности сети.
  • Возможности медиа.
  • Безопасность.

Сборка и развертывание

Обе технологии — кроссплатформенные и используют один и тот же подход: у них есть собственные части для Android и iOS, и включают кроссплатформенные среды выполнения, будь то JavaScript или Dart. Это можно представить следующим образом:

Сборка

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

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

Управление зависимостями

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 репозитория.

Публикация

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

Однако между RN и Flutter всё же есть различия.

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

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

Наличие библиотек и виджетов

Библиотеки и компоненты сторонних сторон

React Native присутствует на рынке уже более 5 лет и располагает тоннами библиотек для различных случаев, начиная с push-уведомлений, воспроизведения видео и компонентов материалов, заканчивая камерой (включая Firebase ML Kit) и интеграциями Apple HealthKit и Google Fit. Существует тщательно подобранный список высококачественных сторонних компонентов, которые можно использовать в своем приложении, под названием awesome-react-native.

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

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

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

Виджеты

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

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

Инструменты и тестирование

Мне кажется, что в этом обе примерно технологии равны. Оба стека включают:

  • Инструменты стиля и качества кода (eslint, tslint, prettier vs dartanalyzer).
  • Unit-тесты (с Jest-тестом и Flutter-тестом).
  • Тесты компонентов (снимки, Enzyme-тесты и виджет-тесты, «золотые тесты»).
  • e2e тестирование (Detox vs e2e).

Производительность

Производительность следует рассматривать с нескольких точек зрения:

  • Производительность рендеринга
  • Собственное взаимодействие
  • Время запуска

Производительность рендеринга

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, кажется, уже решил эту проблему.

Опыт разработчика (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

Сетевые возможности

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 вызывает определенные проблемы, прочитать про которые можно тут.

Медиавозможности

Обе технологии сильно зависят от базовых платформ. Никакие фреймворки для 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.

Безопасность

React Native завязан на js и приложение на его основе содержит js bundle. Но его всегда можно извлечь и понять логику приложения, или изменить ее. Похоже, это серьезная проблема.

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

Вывод

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

  • Недостаток библиотек для Flutter.
  • Обучение Dart новым разработчикам, так как таких разработчиков на рынке нет/мало.
  • Неполные медиа-возможности для Flutter.
  • Более длительное время запуска React-Native.
  • Более низкая безопасность для React-Native.

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here