В чем разница между React Native и Flutter?

Какая техническая разница между React-native и Flutter?

Обе технологии, кажется, делают относительно одно и то же, и Флаттер даже признает, что для этого нужно вдохновение от React: faq

Это становится еще более очевидным, когда они перечисляют одни и те же функции и имеют почти одинаковый синтаксис (StatefulWidget против класса Component).

Аналогично AngularDart, являющемуся реализацией Dart для Angular; Правильно ли предположить, что Flutter - это реализация React в Dart?

Ответы

Ответ 1

Архитектурно React Native (RN) и Flutter очень похожи.

То, что Флаттер называет "виджетом", является строгим эквивалентом React "Компонент". Это то, что Флаттер имеет в виду, когда говорит, что оно вдохновлено React.

Разница между ними заключается в других аспектах структур:

Интерпретированный Javascript VS скомпилированный дротик

Flutter использует Dart, типизированный язык, который предлагает компиляцию "Just in time" (JIT) и "Ahead of time" (AOT) (с включением встряхивания дерева)

В процессе разработки Flutter использует JIT-компиляцию для расширения возможностей горячей перезагрузки. А для производственных сборок он использует компиляцию AOT для лучшей производительности.


React-Native использует Javascript, улучшенный некоторым синтаксическим сахаром, называемым JSX.

JSX - это другой язык, он компилируется в JS, а затем оценивается во время выполнения.

Мост на родной VS Полное переписывание

React родной построен на вершине родной.

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

Мы можем рассматривать React как общий язык между Android/iOS для объявления макетов, но в основном приложения отличаются друг от друга потенциальными несоответствиями.

Это не настоящий кроссплатформенный. Но в то же время это обеспечивает лучшую совместимость с нативными элементами.


Флаттер это противоположность. Цель Flutter - использовать как можно меньше нативных элементов.

Flutter запрашивает у ОС окно, а затем полностью управляет его содержимым с помощью Dart и Skia (это графический движок c++).

Это имеет несколько последствий:

  • Флаттер должен был переопределить всю логику интерфейса. Будь то прокрутка, сенсорные события, анимация,...
  • Приложение написано полностью в дартс, даже глубоко в нижних слоях. Это означает, что какой бы ни была платформа, это всегда один и тот же код, который выполняется.
  • Потенциально все, что может запустить код Dart и создать окно, может запустить Flutter, и приложения должны работать практически без изменений. Таким образом, веб находится в процессе разработки (Hummingbird) и доступна базовая поддержка настольных компьютеров.

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

Ответ 2

У Реми уже есть пара хороших моментов. У меня есть еще один.

Интерпретируется с мостами - против родного и без мостов

Несмотря на то, что название может означать, приложения React Native не скомпилированы в нативный код. Приложения React Native интерпретируют код Javascript во время выполнения, а обновления компонентов в приложении React Native проходят через мост к аналогу собственного представления. Это может немного замедлить ход событий и стать узким местом.

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

Танцуй обезьяну, танцуй

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

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

интерпретаторы

Поскольку Javascript не является языком первого класса для Android или iOS, ваше приложение React Native включает в себя интерпретатор Javascript, который интерпретирует ваш код Javascript во время выполнения. Без переводчика вы вообще не сможете писать приложения с использованием Javascript - даже простой console.log('Hello World!') будет работать.

Согласно документации React Native, в "большинстве случаев" код Javascript будет интерпретироваться с помощью JavascriptCore.

Мосты

Под капотом React Native использует собственные представления Android и iOS UIViews для отображения компонентов пользовательского интерфейса (например, танцующих обезьян) на экране. Но так как части пользовательского интерфейса SDK для Android и iOS не используют Javascript, вы не можете заставить обезьяну танцевать, используя только Javascript.

Это где мост вступает в игру. На другой стороне моста находятся ваши компоненты и логика React Native, написанные на Javascript. С другой стороны, у нас есть хост-приложение для Android/iOS, которое отображает нативные виды на экране. Отныне давайте называть две стороны моста землей Javascript и родиной.

Итак, что происходит, когда пользователь нажимает на нашу "танец, обезьяна, танец!" кнопка?

  1. Собственное представление Android/iOS отправляет событие onclick, которое проходит через мост к земле Javascript.
  2. Наш слушатель onclick, написанный на Javascript, вызывается. Это простой вызов, который переключает логическое значение внутри компонента. Нечто setState(() {isMonkeyDancing = true}) на setState(() {isMonkeyDancing = true}) или подобное.
  3. Реакт видит, что что-то изменилось. Он предлагает обновленное представление элементов пользовательского интерфейса с танцующей обезьяной. Представление - это просто дерево простых объектов Javascript, которое описывает обновленное состояние пользовательского интерфейса.
  4. Дерево объектов Javascript сериализуется и отправляется по мосту на родину.
  5. Хост-приложение получает сериализованное дерево объектов и десериализует его. Теперь он может обновлять собственное представление Android/iOS, чтобы соответствовать десериализованному представлению пользовательского интерфейса. Наша обезьяна сейчас танцует, а наш пользователь вечно счастлив.

Таким образом, в этом примере нажатие одной кнопки требовало перехода по мосту два раза.

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

Это медленнее, чем просто придумать представление пользовательского интерфейса и напрямую обновить пользовательский интерфейс. Кроме того, затраты времени на интерпретацию Javascript во время выполнения сравниваются с тем, что код компилируется заранее.

Суть

Поскольку Flutter по сути является переносимым механизмом рендеринга, Flutter не нужен мост для обновления пользовательского интерфейса. И поэтому обновления пользовательского интерфейса, по крайней мере, теоретически, происходят быстрее. Это одна из причин, почему создание приложений со сложной анимацией или такими вещами, как Flare, SpriteWidget или даже игры, будет более прибыльным с Flutter по сравнению с React Native.

А поскольку Flutter в режиме релиза скомпилирован AOT, Flutter также не нуждается в интерпретаторе. В этом разница между Flutter и React Native.