React Native: очередная «серебряная пуля» для кросплатформенной разработки?

    Есть революции, которые происходят незаметно. Когда разработчики Facebook выпустили фреймворк React Native, никто не захватывал мосты и телеграфы. Новому подходу к кроссплатформенной разработке мобильных приложений удалось взять в плен самое ценное – мозги нативных программистов. Рассказать о центральной идее React Native, его преимуществах, перспективах и недостатках мы попросили Владимира Иванова.



    Владимир более шести лет занимается разработкой под Android, обладает опытом создания приложений под iOS и Windows Phone. Последний год он увлекся React Native и начал двигать культуру кроссплатформенного кода в EPAM Systems.

    — За что Вы не любите платформенный код? Какие недостатки видите в нативной разработке?

    Владимир Иванов:
    Когда заказчик говорит, что хочет мобильное приложение под все платформы, он не понимает, что Android, iOS и Windows — это принципиально разные вещи. Разработчикам программного обеспечения приходится повторять один и тот же код, одну и ту же бизнес-логику на двух или трех платформах.

    Сами платформы тоже имеют многообразие. В iPhone на iOS могут быть варианты по версиям, возможностям, по размеру экрана. А в Android это достигает катастрофических масштабов: нужно поддерживать не только версии, начиная с 2.3, но и огромное количество устройств. Это превращает нативную разработку в довольно утомительное занятие.

    Приведу пример. У меня на Github лежит образовательный проект Flick Feed на React Native. Там порядка 100 строчек кода суммарно для двух мобильных платформ.  И есть подобный проект на BitBucket на Android, который я делал несколько лет назад. Там кода до чертиков, на порядок больше, и это только приложение под Android! Вот смотрите:

    <?xml version="1.0" encoding="utf-8"?>
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:background="#FFF"
                  android:orientation="horizontal"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent">
    
        <ImageView
                android:id="@+id/thumb"
                android:adjustViewBounds="true"
                android:layout_margin="10dip"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
    
        <LinearLayout
                android:orientation="vertical"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
    
            <TextView
                    android:id="@+id/published"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/common"/>
    
            <TextView
                    android:id="@+id/desc"
                    android:ellipsize="end"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    style="@style/common"/>
        </LinearLayout>
    
    </LinearLayout>

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

    Этот же элемент в RN занимает 21 строку, причем логика установки значений уже есть, а inflate вообще не нужен, смотрите

    import React from 'react';
    import { View, Image, Text } from 'react-native';
    
    export default ({ flickrItem }) => {
    
        return (
            <View style={{ flexDirection: 'column', padding: 8, borderWidth: 2, borderColor: 'black', margin: 8 }}>
                <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
                    <Text>{flickrItem.title}</Text>
                    <Text>{flickrItem.date}</Text>
                </View>
                <Image source={{
                        uri: flickrItem.url
                    }}
                   style={{
                       marginTop: 16,
                       width: 200,
                       height: 200
                   }}/>
            </View>);
    }

    Попытки создать удобный кросс-платформенный фреймворк для мобильной разработки идут уже несколько лет. Ни явного лидера, ни «серебряной пули» так и не появилось. Почему?

    Владимир Иванов:
    С момента появления Android и iOS существует приличное количество решений, которые пытаются решить проблему шаринга кода. Это PhoneGap, Titanium и другие.
    Я вижу в своей практике, что люди используют такие фреймворки только для проверки бизнес-идеи. Они позволяют понять, что приложение действительно может быть рабочим, им удобно пользоваться, бизнес-идея нормальная. Если все так, то дальше все делается заново по-нормальному в нативной разработке.

    Эти фреймворки по сути предоставляют WebView и возможность написать на html + css + js то, что будет в этом WebView крутиться. Соответственно, вы понимаете, что качество самих приложений, User Experience, которое это решение может предложить, не самое лучшее. Точно не то, что вам может дать сама платформа.

    — Чем React Native отличается от других фреймворков?

    Владимир Иванов:
    React Native лучше тем, что у вас нет никакого WebView. Он использует родные компоненты пользовательского интерфейса Android, iOS и Universal Windows. Такая реализация позволяет раскрыть всю мощь платформ: интерфейс не тормозит и выглядит нативно, что предполагает качественный UХ.

    React Native вырос из ReactJS, который в свою очередь появился потому, что разработчикам Facebook было не очень удобно в традиционных средствах веб-разработки поддерживать свои приложения. Особенность ReactJS — наличие слоя рендерера, позволяющего промежуточный язык JSX отрендерить в HTML, который уже воспринимается браузером.

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



    — В React Native есть такая штука, как виртуальный DOM. Это и правда классное решение, которое ускоряет разработку приложений?

    Владимир Иванов:
    React построен таким образом, что главное занятие его компонентов — только отобразить состояние. Метод render(), который есть у компонента, смотрит в State и рисует содержимое на его основе. Когда State меняется, React пересоздает целиком дерево своих компонентов. Вот это дерево называется виртуальным DOM.

    То есть когда у вас меняется состояние, необходимо перерисовывать всю страницу заново. Но это плохо с точки зрения перформанса. Что делает React? Он в своей памяти хранит старое и новое дерево компонентов виртуального DOM, вычисляет разницу и на реальном DOM применяет только ее. В виртуальном DOM происходит полная перерисовка, а в реальном — только частичная. Рендеринг происходит очень быстро, а код пишется просто.

    Как соотносятся элементы, которые используются в React Native и в нативной разработке?

    Владимир Иванов:
    Некоторые элементы похожи на нативные. Например, текстовый ввод. Но мощь React Native в том, что вы можете создать собственные компоненты под свои нужды. Вы всегда можете написать обертку над нативными средствами для своего React Native и продолжать в JavaScript считать, что у вас кросс-платформенное приложение.
    Очень много вещей так и работают, например, Push-нотификации. Существует решение, которое имплементируется в Java-код для Android, в Objective-C для iOS. Дальше этот NPM-модуль подключается к вашему проекту, и у вас появляется JavaScript-интерфейс для Push-нотификаций. Если нужен доступ к низкоплатформенным вещам, вы всегда сможете их обеспечить.

    — Какие недостатки есть у React Native?

    Владимир Иванов:
    Если у вас есть строгие требования к интерфейсу для разных платформ, и он сильно отличается в разных версиях, вам придется дублировать значительную часть UI.
    Но бизнес-логику вы все равно сможете оставить кросс-платформенной. То есть, используя какие-то внешние хранилища для стейта и создав правильную архитектуру для React Native, вы все равно сэкономите большое количество усилий.

    Конечно, не стоит забывать, что React-Native — технология молодая и без «косяков» не обойтись. Например, крупный такой «косяк» — навигация. Несмотря на то, что RN прошел уже 4 стадии переделки навигации (Navigator, NavigatorIOS, NavigationExperimental, … ), пристойного решения так и нет. Обещают, что следующая навигация уж точно будет хорошей, но, как известно, обещанного ждут три года.



    Что надо изучить, чтобы начать работать с React Native?

    Владимир Иванов:
    Разработчику в первую очередь нужно знать JavaScript и его стандарт ES6. Вся мощь Babel нужна, чтобы не писать везде React.createClass и остальной Boilerplate. Поэтому рекомендую изучить ES6.

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

    Конечно, есть сложные темы — внешний State, валидация форм, использование контекста в React Native. Про эти вещи я расскажу на Mobius 2017, так что можно прийти послушать.

    Желающим изучить React Native нужно читать Getting Started от Facebook. Также рекомендую курс на Udemy. Кроме того, стоит следить за гуру, которые занимаются React. Я рекомендую твиттер Дэна Абрамова, он достаточно много пишет про React Native.

    Конечно, есть целая печалька в том, что если вы приходите из области, в которой мобильных приложений ни разу не касались, то вам нужно проходить этот квест про установку родных сдк, поднимать эмуляторы, выкачивать гигабайты сдк, и это все более-менее ручной процесс. В итоге вам все равно нужна экспертиза по мобильной разработке, иначе даже не начать. Но буквально неделю назад на React Conf представили аналог create-react-app для React Native: create-react-native-app. Для мобильного разработчика это конечно шок: как, мобильное приложение без приложения! Но для старта это пожалуй идеальный вариант: скрипт вам все сам настроит и поднимет, никаких сдк качать не надо, приложение можно сразу увидеть на телефоне.


    Чем вас так увлек React Native?

    Владимир Иванов:
    Как разработчика, вау-эффект меня накрыл от того, что подход к разработке мобильного приложения, UI целиком другой. В Android, iOS вы сталкиваетесь с императивным программированием, то есть «Эй ты, сделай это, скрой кнопочку, вот здесь помигай» — ты отдаешь команды UI, что ему делать. А в React Native подход совсем другой, нужно немножко поломать себе мозг, чтобы на него перейти. Это полная смена модели разработки, она меня приятно шокировала.

    Я думаю, вся индустрия начнет в ближайшее время мигрировать на эти инструменты, потому что они реально хорошие. Тем более, что React Native – это опенсорсное решение, вокруг которого активно формируется крутое сообщество. Вот UberEats опубликовали, как они использовали React Native в своих продуктах, они и пишут: не беремся утверждать, что пуля серебряная, но нам отлично подошла.



    О том, как в React Native создавать полноценные коммерческие проекты, Владимир Иванов расскажет в докладе «React Native: Уроки выживания» на конференции Mobius, которая состоится 21-22 апреля 2017 года в Санкт-Петербурге.
    JUG.ru Group 1 151,88
    Конференции для взрослых. Java, .NET, JS и др. 18+
    Поделиться публикацией
    Комментарии 34
    • –3
      А теперь сравните итоговый размер двух проектов этих и их производительность/ресурсоёмкость.
    • +3
      RN не есть серебряная пуля. Тот же NativeScript чуть интересней смотрится и имеет более низкоуровневое взаимодействие. Помимо есть Xamarin. По поводу XML для андроида — пора уже понимать что это прошлый век и стоит перейти на Kotlin + Anko (отличнейшая штука) Кроме того DSL есть и для IOS (либу не помню сейчас)
      • 0
        Kotlin + Anko хорош, но тоже не серебряная пуля. Пойдет для небольших «гуешных» элементов — кастомные вьюхи для диалогов, лейауты с 1-3 элементами. В андроиде сейчас constraint layout наконец-то релизнулась, и, на мой взгляд, обещает быть лучше, чем тот же strory board в xcode. Поэтому тут я за него всеми руками ))
        • +1
          Да, для мелких диалогов типа «если хотите, поставьте этот крыжик» реально удобно.
        • 0
          К сожалению, Xamarin выдаёт очень жирные бинарники. И если на iOS ещё удаётся добиться нативной производительности приложения, то с андроидом хуже, в частности из-за необходимости взаимодействия двух рантаймов. Не подскажете, актуальны ли подобные проблемы для RN и NativeScript?
          • 0
            Как это не серебряная пуля? Если она позволяет единожды написать общий код, а работает быстро, как нативный?
            • 0

              Стоит упомянуть и https://flutter.io

            • 0
              Опять Titanium смешали с PhoneGap. Это совсем разные вещи!
              • 0
                Насчет императивного подхода я не совсем понял. В чем проблема юзать тот же Rx, DataBinding, KVO?
                Насчет экономии времени есть кто-то кто уже что-то прям серьезное на этом написал и его можно пощупать? (Кроме команды Facebook)
                • 0

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

                  • 0
                    А есть полноценный апп (AppStore, Play Market) с реализацией?) Интересно было бы посмотреть чего можно добиться с помощью RN, чтобы решить погружаться в это или нет)
                    • 0

                      2гис аптеки

                    • 0
                      Airbnb и Discord. Discord вообще очень сложное приложение.
                      Я уже несколько средних по сложности приложений разработал на React Native. Могу сказать, что плаформа готова для серьезной разработки.
                      • 0
                        https://facebook.github.io/react-native/showcase.html
                  • 0

                    А Ionic Framework?
                    Он действительно на столько плох?

                    • 0
                      Скажу так: заказчики регулярно спрашивают, сколько будет стоит переписывание с Ionic на натив.
                    • +1
                      Я люблю реакт и постоянно его использую его в работе. И так уж получилось вступить в RN. И вот что скажу: по началу была эйфория, было действительно круто. Но чем дальше в лес — тем толще партизаны. React Native просто омерзительно сырой. В нём огромное количество багов, устаревшая документация, есть проблемы с апгрейдом на новую версию. Сейчас дошло до того, что чистый init проект под ios не компилится из-за ошибок. Для работы с RN в любом случае нужен iOS-разработчик и человек который варится в этой кухне, потому что многие вещи нигде не задокументированы. Технология очень перспективная, но в будущем.
                      • 0
                        Частично соглашусь, но только частично. Апгрейд — это попаболь, скрипт либо все файлы переписывает, либо ничего не мигрирует. Роутинг проблемный, документация устаревает очень быстро. Но вот то, что вам нужен iOS разраб… Ну вам надо сплеш сверстать и в стор билд залить, разработчик — это оверкилл.
                        • 0
                          Для апгрейда они сделали git-based инструмент для нормального мержа, чтобы не переписывать ничего полностью, но что-то у меня он сделал почти ничего существенного. В iOS куча своих проблем, которых нет в Android и часто приходится ковыряться в xcode, я не говорю что нужен крутой спец, но нужен кто-то, кто хоть немного разбирается в iOS-разработке.
                          • 0
                            (не могу отредактировать коммент, дополню)

                            Например открытие url, пуш уведомления, сертификаты, линковка (хотя автоматическая наконец начала нормально работать) и прочее — это надо сначала разобраться во всей apple-вской кухне. Особую боль вызывает когда вдруг начинают лететь ios ошибки после апгрейда и ты, не ios-разработчик, понятия не имеешь что с ней делать. Вот тогда приходится тратить время и разбираться.
                            • 0
                              Мне кажется в принципе, чтобы хорошие вещи деллать на RN нужно быть кроссплатформ-нативным разработчиком (то бишь уметь и в Android и в iOS) + знать JS. Это может быть перспективно в случае, если RN станет стандартом кроссплатформ разработки, чего я пока что не наблюдаю, и как следствие появится огромное коммьюнити, а пока честно говоря мне быстрее будет пару нативных приложений создать, чем одно RN, да и работать оно будет получше я так чувствую )
                              • 0
                                технологии полтора года, подождите. Насчет не наблюдаю: в прошлом году про RN на мебиусе никто не говорил, на этом — два доклала. Убер сказал, что их uberEats использует RN… Ну, вы поняли.
                                • 0
                                  >> Убер сказал, что их uberEats использует RN
                                  как я понял, использует бизнес — апп, а не тот, который юзает пользователь из магазина.
                      • 0
                        Автору нужно немного аккуратнее приводить примеры технологий, которые он не знает. В Titanium нету WebView и работает он по тому же самому принципу, что и React Native — управление нативными компонентами из js. React Native — это то, чем должен был стать Titanium, но за 7 лет так и не смог. Его убили маркетологи и эффективные менеджеры.

                        И да, насчет императивного подхода странный аргумент. Хватает способов писать декларативно в нативной разработке.

                        Удивлен, что в епаме стали применять React Native :)
                        • 0
                          Говорят, что у RN одна очередь событий, и в итоге нельзя использовать async вещи которые предоставляет платформа.
                          • 0
                            Эм, что? Можете пояснить, пожалуйста?
                          • –2
                            Простите, но в React Native нет DOM.
                            • 0
                              Можно сколько угодно минусовать, но от этого ни реальный DOM, ни виртуальный там не появится
                              https://github.com/acdlite/react-fiber-architecture#reconciliation-versus-rendering
                              • 0

                                Так и чего? Там написано " Virtual dom is a bit misnomer ". Тем не менее нигде не написано, что принцип работы другой, все равно строится дерево компонентов, а при апдейте сравнивается. Так что это подкоп к терминологии.

                                • 0
                                  Согласен с blackPeanut. DOM подразумевает работу с документами (Document Object Model, все-таки), которых просто не существует в мобильной разработке. Вы не представляете документы, используя объектную модель, Вы используете древовидную структуру для представления компонентов экарн(а|ов).

                                  Более того, VDOM, как таковой, является структурой для представления DOM в памяти и не подразумевает никаких «встроеных» алгоритмов (однако, почти все известные VDOM имплементации поставляются вместе с набором алгоритмов типа обхода дерева, вычисления разницы деревьев и пр).

                                  Прошу не считать это «подкопом» к терминологии, скорее небольшой семантической поправкой статье.
                            • 0
                              Забавно получается:
                              «Отличная вещь! Только навигация в приложении будет кривая хоть ты тресни!»
                              • +1
                                В каждой платформе есть проблемы. Когда проблемы не решаются, от платформы отказываются. Когда решаются — используют. Помните, что продукт, написанный неидеально, но выведенный на рынок, всегда лучше идеального, но остающегося неизвестным никому, кроме создателя.

                              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                              Самое читаемое