Стоит ли инвестировать во Flutter. Сравнение Flutter и React Native

Kate

Administrator
Команда форума

История возникновения​

В начале стоит рассказать о предпосылках и истории возникновения Flutter. Все началось еще в 2014 году. В погоне за скоростью, команда Google Chrome экспериментировала с рендерингом содержимого страниц. Целью эксперимента являлась проверка: можно ли ускорить рендеринг, если отказаться от традиционной модели лейаута, попутно избавившись от груза обратной совместимости, накопившейся за многие годы существования веба.

Основой для экспериментов стал движок Blink, а результатом — прирост производительности в 20 раз за счет следующих изменений:

  1. Простой набор ограничений, влияющих на положение элемента на экране (Box Model) — минимальная и максимальная ширина и высота.
  2. Вместо большого набора правил, который может быть применен к любому элементу, каждый компонент определяет свою простую лейаут-модель (центрирование, паддинг, колонка).
Малое количество правил позволяет существенно оптимизировать лейаут на уровне компонента. А простая модель ограничений, распространяющаяся от родителя вниз по дереву, позволила добиться линейной зависимости между количеством элементов в дереве и временем лейаута. Все происходит настолько быстро, что Flutter не разделяет «создание» и «модификацию» нод. Вместо этого, в случае изменений родительского виджета, он инвалидирует все поддерево.

Результат этого эксперимента был взят за основу при разработке Flutter.

Откуда взялся Dart​

Изначально Flutter был смесью С++ (часть движка Blink) + JavaScript, который использовался как основной язык для написания кода. Но у разработчиков возникли проблемы с JS. Решили поискать другой язык ему на замену. Команда исследовала больше десятка языков и выбрала Dart как наиболее подходящий. Основными преимуществами Dart являются:

  1. АОТ-компиляция. В результате имеем АРМ или х86 код с высоким быстродействием на пользовательском устройстве.
  2. JIT-компиляция. Дает возможность запускать проект в виртуальной машине на эмуляторе и реализовать hot reload длительностью менее одной секунды с сохранением состояния приложения.
  3. Строгая система типов. Позволяет забыть о выборе между TS и Flow.
  4. Tree shaking compiler. При сборке приложения удаляет весь неиспользуемый код.
  5. Generational garbage collection. Быстрое выделение и очистка памяти.

Компоненты фреймворка​

Fl1.png


Flutter состоит из трех слоев: Embeder, Engine и Framework.

  1. Embeder. Платформозависимый код, отвечающий за взаимодействие и запуск на конечной платформе.
  2. Engine. Написан на С/С++ и включает в себя Dart как уровень абстракции для работы с CPU, Skia — 2D библиотеку для рисования и подсистему для рендеринга текста, одолженную у Android.
  3. Framework. Cамая большая часть, полностью написанная на Dart. Разделение на слои позволяет легко построить приложения любой сложности. Можно использовать готовые виджеты из Material-UI или реализовать специфические компоненты на основе базовых виджетов. Есть возможность гибко работать с анимацией и обработкой жестов. Таким образом, можно комбинировать быструю работу с высокоуровневыми виджетами с возможностью внесения/переопределения более глубоких слоев.

Архитектура​

Fl2.png


Особенностью архитектуры Flutter является то, что он сам рисует каждый пиксель, контролирует жесты и анимацию. Он не использует ОЕМ-виджеты, как это делает React Native. Вместо этого, команда Flutter создала два набора виджетов для основных мобильных платформ: Material для Android и Cupertino для iOS. Таким образом, они заново отрисовали все UI-компоненты с обеих мобильных платформ, полностью повторив их поведение. Непосредственно с мобильной платформой (геолокация, звук, bluetooth) взаимодействие происходит через Platform Channels.

Фокус на потребителе​

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

Slow development. Медленный цикл разработки из-за необходимости каждый раз компилировать приложение при внесении изменений. Дополнительным неудобством является сброс состояния приложения. Допустим, проблема находится на третьем шаге мастера. При попытке исправить ее, нужно на каждое изменение в коде или заново проходить все предыдущие шаги, или с помощью ухищрений сделать так, чтобы приложение запускалось с нужного места.

Cross-platform look and feel. При разработке бывают случаи, когда приложение должно выглядеть одинаково на обеих платформах. Учитывая особенности платформ, иногда этого довольно сложно добиться.

Platform diversity. Разнообразие вендоров, которые делают устройства на платформе Android, бывает, сказывается неожиданным образом на том, как выглядит и работает мобильное приложение.

Две команды. При разработке отдельных приложений для iOS и Android, приходится содержать две команды, которые разрабатывают одни и те же функции. А также есть необходимость синхронизировать релизы при вводе в строй мажорных обновлений, чтобы пользователи одной из платформ не были ущемлены в функционале.

Polishing. При кроссплатформенной разработке, отдельным процессом стоит упомянуть полировку верстки, которая, например, на iOS выглядит хорошо, а на Android содержит изъяны. И наоборот.

Performance. Производительность итогового решения при кроссплатформенной разработке иногда оставляет желать лучшего. Те же Cordova и React Native могут доставить немало головной боли.

В итоге нам предлагают:

Fast development cycles. Обновление приложения с полным сохранением состояния в эмуляторе занимает меньше секунды (в большинстве случаев).

Up to 120 FPS. Разработчики заявляют о готовности платформы рендерить на скорости вплоть до 120 кадров в секунду.

Pixel perfect rendering. Flutter заведует всем на экране. Рендерингом каждого пикселя, анимацией, обработкой жестов. Это позволяет добиться максимального сходства в работе на разных платформах и минимизировать влияние платформы на итоговый внешний вид приложения.

Rich set of customizable widgets. Вместе с фреймворком поставляется готовый набор легко катализируемых виджетов, который покрывает все гайдлайны Material-UI и реализует набор специфических для iOS виджетов.

Supports iOS, Android, Web, Desktop. Фактически, архитектура позволяет Flutter работать на всем, у чего есть GPU и экран. Сейчас поддерживается iOS и Andorid. Web и desktop — в активной разработке.

One team. Одна команда и одна кодовая база позволит существенно сэкономить на разработке.

Несмотря на молодость фреймворка, он получил широкое распространение еще до релиза первой версии. Самыми скачиваемыми приложениями, использующими Flutter, являются:

  • Xianyu — 50 000 000+ загрузок;
  • GoogleAds — 5 000 000+ загрузок;
  • Hamilton Musical app — 500 000+ загрузок;
  • Reflectly — 100 000+ загрузок (приложение было полностью переписано с React Native на Flutter).
К релизу первой версии Flutter состоялся Flutter Live Event, на котором фреймворк представили широкой публике. Вместе с ним представили инструмент Flare для создания анимаций и CI/CD-систем от Codemagic специально для Flutter. Анонсирован широкий набор инструментов для разработчика и поддержка основных IDE:

  • AndroidStudio;
  • Intellij IDEA;
  • VSCode.
В дополнение к этому, есть сайт, на котором перечислено огромное количество приложений, написанных на Flutter. Есть отдельная книга, которая распространяется бесплатно и описывает опыт и истории успеха разработки 17-ти приложений с помощью Flutter.

Как уже упоминалось выше, Flutter сконцентрирован на решении проблем бизнеса (стоимость разработки) и разработчика (удобство и скорость). Для этого Google вложил огромные усилия в тулинг для разработки.

Widget inspector. Навигация по дереву виджетов. Щелчок по виджету отправит вас к тому месту, где он вызывается в коде.

f3.png


Debug. Поддержка дебага из окна IDE. Достаточно поставить точку остановки и запустить приложение в debug-режиме.

f4.png


Debug paint. Отрисовка отступов и маркеров позиционирования для быстрого понимания того, что влияет на положение элемента.

f5.png


Repaint rainbow. Постоянно меняющаяся радуга вокруг элементов, которые перерисовываются. Это позволяет отследить нежелательную активность.

f6.png


Performance window. Позволяет следить за скоростью отрисовки и количеством перерисовок отдельных компонентов. Если какой-то виджет будет слишком активным, спиннер слева от колонки окрасится в желтый или красный цвет.

f1.png


Profiling. Используется для глубокой отладки работы приложения.

f2.png


Сравнение с React Native​

Сравнение с React Native я бы начал с github-репозиториев. Это первое, что видит разработчик на подходе к выбору технологии.

Статистика GitHub за июнь 2019 года

React NativeFlutter
Stars~78k~67k
Github issues5135k+
Proposed PR2954
Merged PR0394
Closed issues173619
New issues124822
Из статистики видно, что Flutter молодой и динамично развивающийся фреймворк. По звездному рейтингу он вплотную приблизился к React Native, в то время как по количеству открытых issues, имеет десятикратное преимущество. 5К issues, а также тот факт, что количество новых issues превышает количество закрываемых, говорит о стремительном развитии как комьюнити, так и платформы. Ее активно тестируют и репортят баги. Сюда же стоит отнести и большое количество закрываемых ПР, что также говорит об активном комьюнити и поддержке.

Преимущества, которые обещает нам каждый из пары, я разделил на следующие основные категории:

Write once. Суть кроссплатформенных фреймворков в обещании «написал раз — запустил везде». В обоих случаях на 100% этого не достичь. Но за счет того, что Flutter самостоятельно контролирует отрисовку, жесты и анимации, проблем с подпиранием нюансов той или иной платформы будет всегда меньше. React Native, полагаясь на ОЕМ-виджеты, не всегда может обеспечить гладкий и беспроблемный внешний вид на обеих платформах.

Learn once. React Native, имея в своей основе ReactJS, выигрывает за счет большой популярности как самого языка JavaScript, так и React-фреймворка. Даже если свое знакомство с React вы начнете с React Native, для вас не составит большого труда перейти на web-разработку. И наоборот: имея в штате React-разработчиков, можно достаточно быстро начать работать с React Native. В случае с Flutter, есть большие перспективы с запуском на «любых платформах», но на данный момент он не может состязаться наравне.

Bundled components. В комплекте как с React Native, так и c Flutter, идет готовый набор компонентов (UI, анимация, верстка), но преимущество здесь все же за Flutter, так как каждый из существующих компонентов будет отрисован на обеих платформах. Возможно, некоторые будут смотреться чужеродно на сторонней платформе, но вопрос поиска и подбора компонентов на замену iOS-версиям виджетов в Android решается. Хорошим примером будет PickerIOS, аналогов которому по внешнему виду нет в Android. Приходится прибегать к помощи сторонних компонентов, например, ‘recat-native-wheel-picker-android’.

Performance. Итоговое приложение на Flutter будет представлять собой нативный код, который при прочих равных условиях будет всегда быстрее JavaScript.

Third party libs. React Native здесь вне конкуренции. NPM предоставляет нам множество библиотек на любой вкус. В то же время DartPub, ввиду молодости платформы, не обладает подобным богатством выбора. Множество библиотек, если и есть, все еще молоды.

World wide usage. Несмотря на то, что Flutter набирает популярность и имеет активно развивающееся комьюнити в мировом масштабе, он все еще не может обойти React Native по популярности (согласно Google Trends, исключение составляет США).

Developer experience. Сравнивая ощущения при разработке, Flutter нокаутирует React Native по качеству и количеству всевозможных инструментов для разработчика.

Debug and Profiling. Flutter имеет отдельный режим сборки приложения, который помогает в профилировании и отладке сложных кейсов. В то же время для React Native это более трудоемкий и сложный процесс.

Code push. На данный момент аналогов во Flutter не существует. Разработчики утверждают, что эта задача — решаема. Если для кого-то эта функция важна, есть issue на github, за которым можно следить.

React NativeFlutter
Write once+/-+
Learn once++/-
Included components PR-+
Third party libs+-
Performance-+
World wide usage+-
Developer experience-+
Debug and Profiling-+
Code push+-
В итоге, оба фреймворка по абсолютной сумме баллов идут практически наравне: 4,5 (React Native) против 5,5 (Flutter). Но каждый из вас может сделать свой вывод. Кому-то может быть жизненно необходим code-push, и ради этого он готов сражаться со средствами разработчика в React Native. Для кого-то хайповость, инструментарий и потенциал могут стать решающим фактором в выборе в пользу Flutter. Третьим — Dart станет непреодолимой преградой. А четвертым, наоборот, по душе Dart, который они в тайне от всех изучают уже год к ряду. На практике, на итоговое решение влияют не столько звездочки в репозитории и фишки фреймворка, сколько множество факторов окружающей среды конкретного проекта и бизнеса.

Сравнение архитектур​

Fl9.png


С архитектурной точки зрения, у этих фреймворков мало общего. Общим является платформа, на которой запускается приложение, и, в некотором смысле, способ взаимодействия с сервисами, предоставляемыми платформой. В остальном они принципиально разные.

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

Flutter компилируется в нативный код, а React Native выполняется внутри JavaScriptCore, что не самым лучшим образом влияет на скорость запуска и работы приложения. В React Native все взаимодействие с платформой происходит через бридж, который добавляет накладные расходы на сериализацию/десериализацию данных между средой исполнения JS и нативным кодом.

Во Flutter есть Platform Channels, которые работают сходным с бриджем образом, для реализации взаимодействия с сервисами платформы (сенсоры, камера и т.п.), но за счет нативного кода работают существенно быстрее. Стоит также упомянуть, что дни бриджа сочтены, так как React Native переходит на архитектуру с JavaScriptInterface, чтобы избавиться от оверхеда на бридже.

Последним отличием является язык, который используется для написания кода. В React Native — это JavaScript со всеми его плюсами и минусами, во Flutter — относительно молодой язык Dart, который в свое время был разработан с целью заменить JS.

«За» и «Против» использования Flutter​

«За»:​

Хайп. Технология явно словила волну успеха, имеет активно развивающееся комьюнити и интересные архитектурные подходы в своей основе. Это, на мой взгляд, залог длительного и успешного существования фреймворка.

Быстрое написание кода. Собственный рендеринг, независимость от ОЕМ-виджетов и богатый инструментарий разработчика существенно ускоряет написание кода и поддержку двух платформ одновременно.

Один и тот же код запускается на двух и более платформах. На данный момент полноценно поддерживаются только iOS и Android. Web и desktop — в активной разработке. Но их выход в продакшн — вопрос ближайшего будущего.

Меньше тестирования. За счет pixel perfect rendering, тестирование и устранение платформо-зависимых багов и нюансов верстки будет проходить существенно быстрее.

Быстродействие. Компиляция в нативный код не оставляет сомнений в этом утверждении.

Одинаковый UI на всех устройствах. При необходимости написать приложение с уникальным дизайном, который должен быть одинаковым на двух мобильных платформах, Flutter становится незаменимым инструментом для кроссплатформенной разработки.

«Против»:​

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

Крутая кривая обучения. Dart добавляет накладные затраты на внедрение Flutter за счет необходимости изучать и вникать в новый язык.

Новые нативные UI компоненты. В случае с React Native, они могут быть подключены в проект достаточно быстро. Во Flutter все новые появляющиеся на стороне платформы элементы UI должны быть заново отрисованы.

Необходимость продать технологию менеджеру на текущем этапе ее развития. С каждым днем это будет сделать все легче и легче. Но на данный момент это довольно сильный барьер. Потенциал отправить в Google graveyard. Судя по вложенным ресурсам и PR-активности, это маловероятный исход, но шанс всегда есть.

Отсутствие вакансий на рынке. На данный момент их очень мало. Это должно измениться в будущем. Но сейчас это может стать препятствием для разработчика, который не хочет вкладывать свои силы в изучение новой технологии.

Опасения, что Flutter не способен закрыть потребности бизнеса. Обещая успешную работу на всем, у чего есть GPU и экран, может оказаться запускаемым везде, но не быть востребованным в бизнесе.

Итоги​

Подводя итоги, хочу провести параллель между Flutter и браузером. Возможно, кому-то это покажется неожиданным, но, на мой взгляд, такая параллель имеет место быть. Так же, как браузер рендерит содержимое веб-страницы на практически любом устройстве и под любой операционной системой, Flutter рендерит виджеты. Вместо HTML+JS связки, во Flutter выступает скомпилированный Dart-код. Вместо протокола HTTP, дистрибуция кода осуществляется с помощью вендор-магазинов.

На сегодня браузеры прочно обосновались на всех платформах и достаточно приемлемо отображают страницы любой сложности. Даже те, которые не были специально для них оптимизированы. То есть это не является чем-то недостижимым.

Я считаю, что успех Flutter остается вопросом времени, умноженном на усилия комьюнити и поддержке Google по написанию production-ready ембедеров для всех самых популярных платформ.

Fl10.png


Flutter завоевывает мировой рынок. В подтверждение этому — карта со списком событий, посвященных Flutter по всему миру: от Нью-Йорка (США) до Уйо (Нигерия), от Токио и Осаки (Япония) до Нюрнберга (Германия).

Источник статьи: https://dou.ua/lenta/articles/flutter-for-mobile-apps/
 
Сверху