Flutter vs React-Native: детальное сравнение
Сравнение Flutter и React-Native от разработчика, который провёл несколько месяцев с первой технологией и имеет много опыта с последней.
17К открытий17К показов
Владимир Иванов
Solution Architect в EPAM
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.
17К открытий17К показов