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

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

Корпоративные мобильные приложения обычно распространяются через внутренние магазины приложений компании. Это дает возможность контролировать доступ к приложениям внутри компании, а также принудительно централизованно устанавливать обновление приложений. Для разработки и доставки корпоративных мобильных приложений необходима соответствующая инфраструктура, известная как Mobile Enterprise Application Platform (MEAP).

Для MEAP проведена аналитика ведущими компаниями Gartner и Forrester и выполнено сравнение существующих платформ и вендоров (Gartner Magic Quandrant и Forrester Wave соответственно). Все лидеры указанных сравнений рассматривают возможность создания нативных и гибридных приложений. Нативные приложение пишутся с использованием языков программирования конкретной платформы (swift или Objective C для iOS, Java для Android). Гибридные мобильные приложение пишутся на JavaScript с использованием различных библиотек и фреймворков.

Использование JavaScript фреймворков позволяет создавать новые мобильные приложения существующей командой front-end разработки. Для компании это означает, что одна и та же команда может выполнять разные задачи — разработка сайтов, разработка мобильных приложений.

Среди фреймворков-лидеров можно выделить два наиболее популярных фреймворка: Ionic 2 и React Native. Далее рассматривается каждый из них по отдельности, а также выполняется их сравнение. Сравнение выполнялось только для двух операционных систем: iOS и Android.

Большинство корпоративных приложений, которые используются на мобильных, весьма простые. Сотруднику предоставляется минимальное количество данных, необходимых для принятия решения. Другой аспект таких приложений — это необходимость вносить данные во время работы. С учетом ограниченности мобильных устройств (по форм-фактору) формы для ввода данных также не будут большими. Эти нюансы учитывались во время оценки созданных мобильных приложений (и их сравнение с нативными мобильными приложениями, написанными на родных для каждой платформы языках). От корпоративного мобильного приложения не требуется сверх-большая производительность (такая как в приложениях с миллионами пользователей от Facebook), необходимо, чтобы такое приложение не «тормозило» на относительно простых формах.

Ionic 2


Ionic Framework — это фреймворк для создания гибридных мобильных приложений. В его состав входит набор JavaScript и CSS компонент, созданных на основе Angular 2, SASS и Apache Cordova. История этого SDK начинается в 2013 году, когда компания Drifty Co. решила создать собственную инфраструктуру для написания гибридных приложений, которая будет ориентирована на производительность и будет построена с использованием современных веб-стандартов. Релиз Ionic 1 – состоялся в мае 2015 года. В 2016 году была выпущена версия 2. Основное отличия второго релиза от первого – это переход с Angular 1.x на Angular 2.х.

По своей сути, Ionic Framework — это дополнение над очень популярным фреймворком Apache Cordova, но со своим мощным CLI (Command Line Interface) и объемной документацией. Следуя принципам Apache Cordova, приложения на Ionic Framework — это гибридные HTML приложения. Такие приложения на телефоне выполняются в специальной оболочке (UIWebView для iOS и WebView для Android), которая позволяет показывать HTML и выполнять JavaScript. Соответственно при работе в приложении пользователь работает как бы в веб-браузере.


Архитектура приложения на Apache Cordova (источник)

Apache Cordova является своеобразной прослойкой между пользовательским интерфейсом и ресурсами устройства. Какие-либо виджеты пользовательского интерфейса или MV* (Model-View) фреймворков не входят в его состав. Если необходимо использовать UI-виджеты и/или MV* фреймворк, то нужно выбрать и включить их в приложение самостоятельно, как ресурсы третьей стороны. Ionic 2 — это один из фреймворков, который предоставляет UI виджеты. MVС модель для него предоставляет Angular 2.

Нативные функции телефона (например, камера, хранилище ключей, GPS координаты) недоступны из веб-браузера. Поэтому для работы с ними используются плагины Apache Cordova. Кроме официальных плагинов есть ряд сторонних открытых плагинов.

React Native


React Native — это JavaScript фреймворк, разработанный компанией Facebook для создания нативных мобильных приложений с использованием JavaScript. История React Native началась в 2013 году с внутреннего проекта хакатона компании Facebook. Впервые публично о React Native рассказали на React.js Conf в январе 2015 года, уже в марте 2015 на F8 объявили, что React Native доступен на GitHub. Фреймворк построен на основе библиотеки ReactJS. React Native использует JavaScript API поверх нативных компонентов. При создании приложения, пишется JavaScript код, который работает с нативными компонентами операционной системы. То есть, React Native использует те же самые фундаментальные стандартные блоки UI что и обычные приложения iOS и Android, не используя при этом ни браузер, ни WebView/UIWebView.


Архитектура приложения на React Native (источник)

Приложение на React Native использует отдельный поток для выполнения JavaScript в устройстве. Этот поток взаимодействует с нативным кодом. Важно отметить, что нативные компоненты (включая элементы пользовательского интерфейса) отличаются для разных операционных систем. И, соответственно, для каждой операционной системы необходимо создавать свои «bridges» между JavaScript кодом и этими компонентами. Ряд таких компонент предоставляет Facebook, а также существует много компонент в свободном доступе, разработанных сообществом.

Ionic 2 vs React Native


Ionic 2 и React Native позволяют создавать мобильные приложения. Принципиальная разница между этими фреймворками заключает в типе мобильного приложения, которое создается с использованием того или иного фреймворка. Ionic 2 позволяет создавать гибридное мобильное приложение, которое осуществляет рендеринг в WebView/UIWebView, при необходимости использовать API платформы нужно использовать дополнительные плагины. React Native позволяет создавать нативное мобильное приложение, используя фундаментальные стандартные блоки UI (как и обычные приложения iOS и Android, написанные на родном языке — Objective-C/Swift и Java соответственно). В приложении на React Native используются определенные шаблоны заданные самой платформой.


Выполнение кода и связь с нативным API в приложениях, написанных на Ionic 2 (слева) и React Native (справа)

Схема показывает составляющие кода приложения и вызов нативного API из приложений. В случае Ionic 2 отрисовку интерфейса пользователя выполняет браузер, в для React Native — непосредственно операционная система. Такое различие проявляется в более привычной прорисовке компонент и более гладкой анимаций приложений на React Native. Пользовательский интерфейс React Native приложений будет ближе к другим приложениям платформы. Ввиду того, что приложение, написанное на React Native, компилируется в нативный для платформы язык, не нужно использовать дополнительные промежуточные компоненты (например, Cordova), часто это дает лучшую производительность приложений. Проблемы с производительностью — одна из проблем Ionic 2.

При возникновении нативного события фреймворки по-разному его обрабатывают. Ionic 2 блокирует поток и передает управление на JavaScript-код, ожидая его инструкций. React Native выполняет JavaScript в отдельном фоновом потоке, взаимодействуя с главным потоком асинхронно.

Код


Для создание приложения на Ionic 2 используются фреймворки Angular 2 и Apache Cordova. Приложение можно писать на JavaScript или любом другом языке, который транслируется в JavaScript. Самым популярным типизированным надмножеством JS является TypeScript, представленный Microsoft в 2012 году и позиционируемый как средство разработки веб-приложений, расширяющее возможности JavaScript, на нем же и реализовано большинство примеров в документации Angular 2. В Angular 2 реализована шаблон проектирования внедрения зависимостей (software design pattern Dependency Injection), который состоит из 3х элементов:

  • Injector — предоставляет доступ к API, для внедрения зависимостей
  • Provider — описывает как создавать экземпляр зависимости; имеет маркер, указывающий на фабричную функцию, создающую объект
  • Dependency — тип, к которому относиться созданный объект

Кроме того, в Angular 2 используется компонентный подход, который позволяет разделить бизнес-логику, работу с фронтом. Кроме того, разделение также используется на уровне элементов проекта: HTML, JavaScript и CSS сохраняются в отдельные файлы.

Для того, чтобы начать писать приложение на React Native нужно познакомиться с ReactJS, JSX. Также для работы рекомендуется изучить Redux и EcmaScript 2015 для ускорения разработки, однако знание этих компонент опционально.

Также можно использовать Flow — это статический анализатор кода и набор синтаксических конструкций, для прямого указания типа переменной. Flow умеет вычислять тип переменной, без внесения изменений в код (в отличии от TypeScript) что позволяет начать использовать его уже сейчас в любом проекте. Есть возможность самостоятельно указывать типы в стиле TypeScript.

В процессе написания приложения на React Native вы создаете компоненты, которые являются самодостаточными, каждый компонент отвечает за изменения в своем состоянии (state). Существуют stateless и stateful компоненты. Компонентам, которые не имеют состояния, можно передавать свойства (props — устанавливаются родительским компонентом и являются фиксированными в течение всего жизненного цикла компонента).

Debug


Отладка приложений в Ionic 2 стандартна для front-end разработчиков. После запуска приложения на эмуляторе/девайсе возможно отлаживать приложения с использованием Safari веб-инспектор (только для iOS) или Chrome Developer tools. Эти инструменты предоставляют доступ к HTML, CSS и JavaScript. Во время отладки есть возможность быстро редактировать стили, искать узлы в html, выполнять и смотреть результат JavaScript функций, а также сетевых запросов. Кроме запуска на устройстве или эмуляторе, в случае Ionic 2 также есть возможность запустить приложение непосредственно в браузере (ionic serve). Это может ускорить разработку, а с помощью команды ionic serve --lab упрощается тестирование приложений на разных диагоналях экранов и платформах.

В Ionic 2 есть опция Live Reload. Она позволяет вносить изменения в код и видеть эти изменения на устройстве/эмуляторе без пересборки. Однако не всегда удается ее использовать. После запуска в связи с работой в веб-браузере при использовании http запросов, сталкиваемся с проблемой CORS.

Для отладки приложений на React Native возможно использовать Chrome Developer Tools. Если же разработка ведется на устройствах от Apple, то возможно использовать веб-инспектор Safari для эмулятора или устройства iOS. Для просмотра элементов view можно выбрать опцию «Show inspector» в Developer Menu эмулятора/устройства. При этом можно увидеть стили элементов, но менять их возможно только в IDE (тут не работает метод быстрого редактирования стилей в developer tools). Но используя опции LiveReload или HotReload уже через несколько секунд сохраненные изменения будут видны на эмуляторе/устройстве. Если внесены глобальные изменения в код, лучше пересобрать проект. Так же в Developer Menu есть вкладка Network, которая позволяет отслеживать HTTP запросы. Тут можно увидеть тип запроса, метод, url и прочее. После дебага в браузере это непривычно. Для дебага также можно использовать IDE для каждой из платформ – Android Studio и XСode, с помощью которых можно детально изучить все логи и работу приложения (ресурсоемкость, скорость работы и т.д).


Пример дебага приложения, созданного на React Native, на смартфоне iPhone 6 (iOS 10.2)

Сборка приложения для дебага написанного на Ionic 2, в браузере, более быстрая чем сборка приложения на на эмуляторе при использовании React Native. Стоит также отметить что старт готового приложения Ionic 2 на устройстве, более медленный чем в подобного приложения на React Native.

Таким образом, отладка приложения на Ionic 2 более быстрая и знакомая для front-end разработчиков.

Стили


В Ionic 2 пишется HTML5 код и используется привычный front-end разработчику SASS. Тут нет ограничений на размерные единицы, используется препроцессор SASS, также можно применить flex разметку. Часто приходилось переопределять переменные Ionic 2. Но иногда этого не хватало, нужно было изучать итоговый html в браузере, смотреть какие дополнительные элементы были сгенерированы и какие у них стили, чтоб понимать, что и где переопределить или дописать. Также ощутимая разница была в отображении элементов на разных платформах. То, что выглядело хорошо на iOS устройствах иногда ломало стили на Android-устройствах, нужно было находить компромиссы.

В React Native создание стилей отличается от привычного для frontend разработчика. Тут используется css-подробный синтаксис, который пишется в виде js объекта. Затем этот объект со «стилями» преобразовывается в понятные для платформы указания по расположению и раскраске элементов.

Верстка выполняется абсолютными значениями, никаких относительных величин. Большим плюсом является использование flex-подобной разметки при стилизации компонентов, что позволяет изменять размеры компонента в зависимости от размеров контейнера. Если указать "flex: 1", то компонент будет занимать все доступное пространство. Если компонентов несколько, то они равномерно распределяют между собой все доступное пространство. Это минимизирует затраченное время на стили, так как такой подход позволит отображать элементы пропорционально размеру экрана. И на телефоне и на планшете получается одинаковый результат, ничего «не уезжает» и «не ползет». Практически всегда для приложений на RN стили валидны для обеих платформ. Если стили все же перебиваются, используется привязка к платформе. Например, в нашем приложение была ситуация, когда нужно было использовать zIndex — на iOS все работало отлично, но на Android это свойство (которое применялось к компоненту Header), способствовало некорректному отображению других элементов интерфейса (Tabs).

Стилизация в Ionic 2 занимала больше времени, чем в React Native. Но дизайн нашего приложения был достаточно простым и минималистичным. Возможно, при разработке сложных дизайнерских решений, имея доступ к полноценному css, Ionic 2 выиграл бы по времени и удобству.

Размеры приложений


Для обоих фреймворков существуют «пустые» приложения – это каркасы приложений с минимальным кодом. Такие приложения генерируются с использованием CLI:

  • Ionic 2: ionic start myApp blank --v2
  • React Native: react-native init AwesomeProject

Пустые приложения собирались в двух режимах: debug и release. Первый режим предназначен для отладки приложения, второй — для непосредственных поставок готовых приложений конечным пользователям.

Ionic 2 React Native
Приложение в режиме debug Приложение в режиме release Приложение в режиме debug Приложение в режиме release
iOS 18.3 Mb 17.9 Mb 4.8 Mb 4.6 Mb
Android 5.54 Mb 4.0 Mb 32.38 Mb 16.35 Mb

Приложения на различных фреймворках имеют различный размер на различных платформах. Ionic 2 выигрывает на Android, а React Native – на iOS.

Популярность и активность фреймворков


При сравнении популярности фреймворков нужно учитывать, что React Native более молодая технология. Изначально у React Native была поддержка только iOS. Поддержка Android в React Native появилась только в августе 2015 года, а Ionic Framework на тот момент уже больше двух лет развивался (хотя и имел версию 1.0) и обладал поддержкой всех популярных платформ.

Популярность и активность сравнивали по двум наиболее популярным ресурсам: stackoverflow и github.

Для Ionic Framework на stackoverflow существует около 60000 результатов по запросам Ionic и Ionic 2. При рассмотрении сатистики по репозиторию Github важно учесть, что в середине 2016 года код Ionic 2 мигрировал в репозиторий Ionic. В репозиторий Ionic более 200 участников сделали порядка 6000 коммитов в 15-ти ветках с 88-ю релизами. В репозитории проекта находится ~700 открытых вопросов и ~9000 закрытых.

Для React Native на stackoverflow существует около 25000 результатов по запросу react-native. Статистика по репозиторию Github React Native показыват большую активность этого фреймворка по сравнению с Ionic 2: более 1200 участников сделали порядка 10000 коммитов в 60-ти ветках с 160-ю релизами. В репозитории проекта находится ~1100 открытых вопросов и ~7000 закрытых.

Статистику использования фреймворков возможно посмотреть на открытых ресурсах (например, на stackshare.io). По статистике NPMTrends (статистика по скачиванию npm пакетов) можно увидеть, что за последний год Ionic 2 уверенно лидирует по скачиваниям, но в последние несколько месяцев React Native вырывается вперед.


Статистика по скачиванию npm пакетов

На сайтах фреймворков также есть примеры уже готовых приложений: приложения на Ionic 2, приложения на React Native. Для обоих фреймворков существует большое количество сторонних Starter Kit, которые помогут создать приложение с готовой структурой (Starter Kits Ionic Framework, Starter Kits React Native).

Разработка и использование фреймворка React Native в последнее время более активные.

Ionic 2 vs React Native: сравнение на примере


Задача сравнения Ionic 2 и React Native на практике была поставлена перед командой front-end разработчиков.

Приложения работы с бизнес-процессами на Camunda BPM


Для выбора фреймворка, который в дальнейшем мы будем использовать для написания мобильных приложений, мы написали мобильный клиент для Camunda BPM. Camunda BPM – это BPMS (Business Process Management System), в которой наша команда backend разработчиков реализовала ряд бизнес-процессов.

Для реализации в мобильном клиенте мы выбрали один бизнес-процесс — процесс «Заявка на технику». Этот бизнес-процесс состоит из нескольких шагов: создание заявки, утверждение различными ролями (руководителем департамента, системным администратором, техническим департаментом, бухгалтерией, заместителем генерального директора), непосредственно выдача техники. Во время выполнения бизнес-процесса заявка может вернутся инициатору на редактирование. Некоторые из шагов утверждения назначаются на группу специалистов.


Диаграмма бизнес-процесса «Заявка на технику»

Форма, с которой работает пользователь, зависит от состояния заявки и прав пользователя. В форму возможно было вносить только текстовые данные. Некоторые формы динамические, например, поле «комментарий» отображается в зависимости от выбранного пользователем действия (Approve/Decline).

В приложении пользователь работает таким образом:

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

    • задачи созданные пользователем;
    • задачи, ожидающие решения пользователя;
    • задачи, которые назначены на группу людей, где пользователь может взять на себя их решение;
  3. Если пользователь имеет доступ к Заявке, то для каждой задачи он может детально ознакомиться с информацией в заявке и просмотреть историю ее прохождения.
  4. Если пользователь принимает решение по заявке, то часть формы Заявки становится доступной для редактирования с опциям для принятия решения.
  5. При работе с Заявками также доступен поиск по задачам, который выводит результаты по запросу пользователя.
  6. В приложении реализована функции аутентификации пользователя.

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

Сравнения готовых приложений


Во время тестирования нашего приложения мы сравнивали скорость рендеринга страницы в зависимости от фреймворка и платформы. Для этого в каждом проекте была создана дополнительная тестовая страница. Данные для отрисовки были сгенерированы в цикле без обращения к серверу. По этим данным создавалось 1000 элементов «Card», время отрисовки которых замерялись. Компонент «Card» eпрощенно его можно представить таким html:

<div>
	<header>
		<h2>Task Name</h2>
	</header>
	<div>
		<h3>Subscribe</h2>
		<span>date</span>
	</div>
</div>

У каждого компонента (актуально для обоих фреймворком), есть жизненный цикл (lifecycle): компонент будет примонтирован, компонент отрисовался, компонент будет удален и так далее. У всех этих фаз есть методы, так называемые lifecycle-methods, именно их мы и использовали для проведения тестов. Тестирование проводилось с использованием методов time() и timeEnd() объекта Console.

Для проекта на React Native метод time() вызвался в componentWillMount (этот метод вызывается только один раз, прежде чем рендеринг происходит в первый раз), а метод timeEnd() вызвался в componentDidMount (этот метод вызывается только один раз, после первого рендеринга).

Для проекта на Ionic 2 метод time() вызвался в constructor (первое событие жизненного цикла, которое запускается при создании страницы), а метод timeEnd() вызывался в ionViewDidEnter (сообщает о том, что все хорошо и что страница полностью загружена и полностью вступила в поле зрения, анимация перехода вместе с любой внутренней настройкой завершена).

Тестирование проводилось на эмуляторе и на устройстве. Тестирование для iOS устройств — на эмуляторе iPhone SE (iOS 10.2), на устройстве — iPhone SE (iOS 10.2.1); для Android устройств — на эмуляторе Asus Nexus 7 (Android 6), на устройстве — Asus Nexus 7 (Android 6.0.1). В таблице представленно среднее время отрисовки 1000 элементов «Сard» в миллисекундах.
Симулятор iPhone SE iPhone SE Симулятор Nexus 7 Asus Nexus 7
Ionic 2 5354.6 — 5272.5 5663.1 — 5859.5 1401.3 — 1750.6 7040.3 — 9385.4
React Native 36.1 — 47.6 32.5 — 35.2 45.4 — 56.1 44.1 — 52.3

Непосредственно для нашего приложения мы провели сравнение использования CPU и памяти для устройств iPhone SE (iOS 10.2.1) и Moto Z Play (Android 7.0).


Использование CPU


Использование памяти

Ionic 2 уступает React Native почти по всем тестируемым параметрам, кроме использования памяти на Android (особенно интересен тест времени загрузки приложения).

Как и в случае «пустых» мобильных приложений, готовые мобильные приложения на различных платформах отличаются в несколько раз.
Ionic 2 React Native
Приложение в режиме debug Приложение в режиме release Приложение в режиме debug Приложение в режиме release
iOS 17.5 Mb 17.4 Mb 6.6 Mb 6 Mb
Android 6.78 Mb 4.6 Mb 33.64 Mb 16.79 Mb

Ionic 2 по использованию CPU и размеру приложения выигрывает на Android. React Native по тем же параметрам – на iOS.

Выводы


Корпоративные приложения для мобильных устройств, созданные с использованием JavaScript, заняли свою нишу. Скорость работы таких приложений достаточна, по сравнению с приложениями, написанными на «родных» языках платформ. В целом нельзя сказать, что какой-то фреймворк лучше, а какой-то хуже. Они просто разные. Выбор зависит от поставленных задач, конечной цели и многих других факторов. В целом можно рекомендовать использовать Ionic 2 для быстрой разработки прототипов мобильных приложений, а React Native — для полноценной разработки готовых решений. Ниже представлен список преимуществ и недостатков каждого фреймворка, основанный на наших впечатлениях использования Ionic 2 и React Native.

Преимущества Ionic 2:

  • известный набор инструментов — для frontend разработчика набор используемых технологий является знакомым, это существенно сокращает время на выполнение поставленной задачи
  • быстрый старт — используя шаблоны приложений предоставленные нам Ionic, можно за короткое время создать прототип для показа заказчику (речь идет только о способах описанных на официальных сайтах фреймворков, сторонние Starter Kit нами не рассматривались)
  • «Write once, run anywhere» — написанное приложение работает на всех популярных платформах, это дает кросс-платформенность с незначительными изменениями кода

Недостатки Ionic 2:

  • стилизация — изменение стилей по-умолчанию для их приведения в соответствии с макетом значительно увеличивает затраты времени на создание и тестирование приложений на разных платформах и девайсах
  • использование браузера — более длительная загрузка приложения и плохая отзывчивость при нагрузке процессора из-за использования браузерной оболочки для имитации поведение компонентов каждой платформы
  • нативные функции — при возникновении нативных событий блокируется главный поток и передается управление на JavaScript-код, ожидая его инструкций, что может приводить к непредсказуемой работе нативных функций

Преимуществ React Native:

  • стандартные нативные блоки UI – использование фундаментальных стандартных блоков UI, что и обычные приложения iOS и Android, знакомые пользователю по другим нативным приложениям, облегчает взаимодействие пользователя с приложением
  • неблокирующее выполнение JavaScript — JavaScript выполняется в отдельном фоновом потоке, взаимодействуя с главным потоком асинхронно
  • стилизация — приложение одинаково хорошо выглядит на разных платформах и устройствах
  • нагрузка на CPU — проведенные тесты использования приложением CPU и памяти показывают лучшие результаты по сравнению с Ionic 2

Недостатки React Native:

  • необходимость работы с нативным кодом платформы — может возникнуть необходимость разбираться в компонентах, написанных на ObjectiveC/Swift или Java
  • сложность старта (без опыта работы с ReactJS) — необходимо дополнительное время на знакомство React, JSX и отличающимся подходом написания (компоненты, как самостоятельные единицы интерфейса, которые сами отвечают за свое состояние и поведение)

Полезные ссылки


Ionic 2


React Native


Сравнение Ionic (2) и React Native

Поделиться с друзьями
-->

Комментарии (39)


  1. nicksyndicate
    18.05.2017 13:02
    +1

    Одно из преимуществ разработки на RN, это быстрый старт с expo.io


  1. search
    18.05.2017 14:49
    +4

    Рёбя, немного не в кассу, но хочу поделиться, как я немного обуздал проблему производительности в Ионике 2 на iOS устройствах. На отдельный хабрапост данный текст явно не тянет, так что оставляю его тут в камменте, не пропадать же знаниям.


    Так вот. Скроллинг для списков >= 100 элементов неприятно тормозил. Тормоза были двух типов:


    1. Небольшая задержка при начале скроллинга
    2. Сам скроллинг работал медленнее в сравнении с нативным

    Решения:


    1. Оказалось что событие onTouchStart (да и вообще любое событие) вызывает перерисовку элементов списка, выполняемого директивой ngFor. Для того чтоб этой перерисовки не было можно поместить код с ngFor в отдельный компонент, а к компоненту применить changeDetection: ChangeDetectionStrategy.OnPush. Как показала практика, changeDetection: ChangeDetectionStrategy.OnPush — довольно неплохое решение для многих проблем производительности в Angular 2. Вот тут подробнее описано как его готовить и с чем его едят. Там есть нью-ансы, рекомендую прочитать перед тем как юзать его на всех компонентах.
    2. WKWebView — ответ на многие вопросы производительности в iOS устройствах. Подробнее тут: http://blog.ionic.io/cordova-ios-performance-improvements-drop-in-speed-with-wkwebview/. Кстати он решает не только вопросы производительности но и проблемы использования современных CSS3 свистелок. НО! тут есть подводный камень, а именно CORS. Если ваш сервер не умеет отдавать access-control-allow-origin хедер, то о замечательном WKWebView можно забыть.

    P.S. А автору спасибо за статью, всё по делу.


    1. Carduelis
      18.05.2017 23:06

      А по какой причине ангуляр перерисовывает элементы по onTouchStart? Я не пишу на ангуляре, а использую реакт для progressive web apps, и подобные проблемы могут поджидать из-за угла тоже. Если ангуляр перерендеривает список, значит тому есть какая-то логичная причина, а значит, она может быть реализована уже в реакте, или, наоборот, ее придется реализовать рано или поздно (ведь неспроста ж она есть в ангуляре). Да, способ ренедеринга разнится, но проблема рендера списка, особенно большого и в скролле, когда туда добавляются/убавляются элементы на лету — как никогда актуальна.


      1. search
        19.05.2017 00:24
        +1

        Я прошу прощения, Ангуляр не обязательно перерисовывает весь дом по событиям, но всегда проверяет, не устарел ли элемент. И перерисовывает его в случае необходимости.


        Вот тут очень подробно описана работа механизма определения изменений. Если в двух словах, то Ангуляр, используя библиотеку Zone.js, патчит некоторые функции API браузера таким образом, что при вызове этих функций дополнительно выполняется проверка на наличие изменений в дереве компонентов. Классический пример подобного патча — нативная функция setTimeout(). Вызов этой функции внутри Angular приложения повлечёт за собой проверку на изменения и перерисовку в случае необходимости. Так же Angular патчит и функцию addEventListener(). Таким образом, если навесить на любой элемент событие (например тот же onTouchStart), то это событие вызовет механизм проверки/перерисовки дерева компонентов. Попытка скролла в Ионике приводит к неизбежному onTouchStart, который вызывает проверку компонентов и тормозит браузер, если компонентов много. Благо, есть способ это отключить.


        А вот как Реакт справляется с определением изменений/перерисовкой компонентов мне самому стало интересно :)


        1. vintage
          20.05.2017 10:16

          То же самое будет и в Реакте, если по onTouchStart изменить что-либо в сторе/стейте.


  1. xGromMx
    18.05.2017 15:36
    +3

    Сделай сравнение с ReactNative и NativeScript


    1. VanDamM
      19.05.2017 09:53
      +1

      +1
      Тоже было бы интересно


    1. yurash
      20.05.2017 19:29

      Да, было бы интересно почитать сравнение именно Native-like инструментов, я на сегодняшний день слышал о (помимо упомянутых):
      tabrisjs
      fusetools
      weex-project.io


  1. nos
    18.05.2017 23:19

    А Васька слушает, да… продолжает кодить на Appcelerator Titanium.


    1. farwayer
      22.05.2017 20:29

      Как человек, который очень много всего разработал на титаниуме, могу только посочувствовать. Переход на React Native был из разряда «как перестать есть кактус и начать получать удовольствие от кроссплатформенной разработки».


      1. nos
        23.05.2017 00:05

        а парочку ссылок на результаты работ сделанных с удовольствием в app store и google play можно посмотреть?


        1. search
          23.05.2017 09:05

          Интересно, какой вывод об удобстве фреймворка можно сделать глядя на аппстор?


          1. nos
            23.05.2017 11:16

            если на «удобном» фреймворке получаются «неудобные» или медленные приложения, то «удобство» фреймворка можно проигнорировать. :)


          1. nos
            23.05.2017 11:21

            бывают фреймворки где «удобно» лепить простые приложения, но шаг влево или вправо возможен только «костылями» и «извратами». Оценить это можно посмотрев сложные приложения вылизаные и опубликованые в аппстор.

            ну и при наличии хорошей наработанной библиотеки компонентов (собственных, а не идущих в пакете) все фреймворки «удобные» по умолчанию.


            1. search
              23.05.2017 12:58

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


              1. nos
                23.05.2017 13:12

                Я писал там выше что мы используем Appcelerator Titanium (но руку на пульсе я держу и за аналогами слежу.). Мне сказали, что ушли с титаниума и стало кодить легче и удобнее. Я удивился ибо пока ничего удобнее и быстрее в разработке не видел и попросил показать результаты в Appstore — интересно сравнить отзывчивость приложений с нативными и титаниумовскими.

                я ни в коем случае не планирова устраивать холивар «титаниум против RN или ионик2» просто напомнил что на JS можно писать еще на одном инструменте и он в отличии от описанных выше заточен под корпоративную разработку.

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


                1. farwayer
                  25.05.2017 01:47

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


                  1. nos
                    25.05.2017 15:19

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

                    Производительность бриджа js-native-js тоже вызывает вопросы — новых технических революций в мире не происходило — скорость бриджа везде примерно одинакова. Или в RN — бридж другой?

                    В Titanium я могу выбирать где крутить JS loop, в main thread или отдельно — в RN — только в отдельной — итого я по отзывчивости всегда выиграю перейдя в main. то что на меня это наложит отдельные ограничения — я понимаю. но отзывчивость разогнать могу.

                    Собственно первый пост был именно об этом — покажите приложение в аппсторе написаное на Реакте — с листанием огромных списков с подчиткой на лету, со сложными вьюхами и анимацией — и тогда можно сравнить — что шустрее.

                    Я могу кинуть ссылок на свои приложения которые в аппсторе на титаниуме и сравним.

                    А иначе это просто треп… лучше, удобнее…

                    Например Hooperloop для подключения нативных модулей без писанины на ObjC и Java — при всей глючности более удобный чем кодить модуль отдельно.


        1. farwayer
          25.05.2017 01:10

          Они, в основном, для внутреннего использования были. Сейчас еще парочка на релиз в AppStore/Google Play готовится. Могу дать знать, когда в релиз пойдут.
          А «на посмотреть» в строрах сейчас хватает: discord, instagram, airbnb — это из крупных.
          https://facebook.github.io/react-native/showcase.html


          1. nos
            25.05.2017 15:25

            то что монстры накодили огромными командами будучи обязаными кодить на RN — это пример так себе — мы не знаем насколько им там было удобно и сколько раз они подпилили RN под себя для этого.

            и сколько раз они изменили свое ТЗ по причине — в RN этого сделать нельзя/геморно/трудно.

            мне интересны приложения от человека который утверждает что приложения (не одно) на RN кодить удобнее и удовольствия больше.

            проблемы начинаются когда заказчик хочет интерфейс и поведение за пределами коробочных решений фреймворка. вот где такое удобнее делать — в этом вопрос. титаниум постарше — от того он и граблей больше перетоптал.

            но суть моего первого поста не меняется — я смотрю на новые инструменты и продолжаю кодить на титаниуме — потому что RN считаю еще не готовым легко «прогнуться» под изменчивый мир под ТЗ заказчика.


          1. nos
            25.05.2017 15:47

            Сходил по ссылке посмотрел Bloomberg
            How Bloomberg Used React Native to Develop its new Consumer App
            https://www.techatbloomberg.com/blog/bloomberg-used-react-native-develop-new-consumer-app/
            https://itunes.apple.com/us/app/bloomberg/id281941097?mt=8

            стартовало приложение крутя реактовский кружок 25 секунда на iphone 6 — дизайн отдельная песня — отзывчивость как у phonegap web приложения. жуть. оценка в аппсторе такаяже — надо удалить ее со страници примеров RN

            а их там целая команда блин…

            вот например простенькое приложение на Titanium
            iOS: https://itunes.apple.com/nl/app/unison-insurance-tvoa-strahovaa/id1135303315?mt=8
            Android: https://play.google.com/store/apps/details?id=ua.com.ugic
            команда 2 человека, 3 месяца разработки. было удобно. удовольствие получено. от нативного не отличишь с первого взгляда (по сути то оно и есть нативное)

            P.S. у всех прошу прощения за оффтоп в ветке про RN и излишние внимание к Титатаниуму. Я не евангелист ихний — просто не могу найти альтернативу. писать сравнительный пост — жалко терять время. поэтому…

            А Васька слушает, да… продолжает кодить на Appcelerator Titanium.

            Больше не буду — я и не планировал уходить дальше первого комента :)


            1. vintage
              25.05.2017 16:53

              Есть альтернатива в виде Кордовы.


              1. nos
                25.05.2017 16:58

                я использовал кордову когда она была phonegapom с sencha touch — лет 5-6 назад — это вообще не нативные контролы или нативные с бубном. об удовольствии речи нет. производительность слабая, внешний вид — притворяться HTML+CSSом нативными элементами — увольте.

                кстати у RN есть репозиторий виджетов которые могут публиковать члены комьюнити чтобы их ставить и юзить потом с пол пинка?

                чувствую таки прийдется написать что-то про титаниум и накидать ссылок. у меня например есть под титаниум OpenGL движок кросплатформенный — можно игры 2.5D лабать. 7 интерактивных сказок в аппсторе 5 лет в топ 100 книг без рекламы.


                1. vintage
                  25.05.2017 17:06

                  это вообще не нативные контролы

                  Кроссплатформенным приложениям и не нужно выглядеть нативными. Мимикрия под натив — это блажь.


                  sencha touch

                  Зачем вы эту гадость трогали? :-)


                  1. nos
                    25.05.2017 17:58

                    кросплатформенный титаниум это именно только нативные контролы и мимикрировать не надо.

                    а sencha — это было требования клиента :(


                    1. vintage
                      25.05.2017 21:32

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


                      1. nos
                        25.05.2017 22:03

                        это как раз и дело фреймворка чтобы я писал в RN а в Android он был ListView а в iOS UITableView — но и там и там должны быть нативные контролы.

                        я создал TabGroup и в результате у андроида он сверху а у iOS cнизу. унификация на плечах кросплатформенных фреймворков — это и удобство и головная боль одновременно


                        1. vintage
                          25.05.2017 22:23

                          Это работает лишь в простейших случаях, когда контролы мапятся 1-к-1 на разных системах. Это далеко не всегда так.


                          1. nos
                            25.05.2017 23:18

                            например?


                            1. vintage
                              26.05.2017 00:25

                              image


                              ios: два вида таббаров
                              android: один вид
                              windows: вообще панорама


                              1. nos
                                26.05.2017 00:26

                                ну и на все три код должен быть одинаков у кроссплатформеного фреймворка. или нет?


                                1. vintage
                                  26.05.2017 00:32

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


                                  1. nos
                                    26.05.2017 00:37

                                    ios — один вид таббара — верхний — buttonbar — оне не переключает окна

                                    для iOS и Android в Appcelerator код будет идентичен. для винды тот же код будет работать но я не уверен в результате — панорама там будет или еще что


                                    1. vintage
                                      26.05.2017 01:14

                                      На картинке вы можете видеть и верхний и нижний.


                                      Подозреваю там будет тыква.


                                      1. nos
                                        26.05.2017 01:15

                                        на картинке — один зовется TabGroup (обьединяет окна) а второй tabbedBar — обьединяет батоны


                                        1. vintage
                                          26.05.2017 08:34

                                          И? Объединённые батоны точно так же переключают вкладки.


            1. farwayer
              25.05.2017 17:56

              Кривые руки испортят любой хороший инструмент. Это я про блумберг. Действительно ужасно работает. Посмотрите discord — действительно сложное приложение и с точки зрения бизнес-логики, и с точки зрения UI.
              Я погонял ваше приложение. Мне кажется, что до нативной скорости работы там далеко.
              Отправил вам в личку видео работы приложения на React Native, которое скоро уйдет в релиз. К сожалению, пока не могу выложить его в открытый доступ.


  1. vintage
    20.05.2017 10:09

    От корпоративного мобильного приложения не требуется сверх-большая производительность (такая как в приложениях с миллионами пользователей от Facebook)

    Число инсталляций как-то влияет на требования к отзывчивости приложений?


    Ввиду того, что приложение, написанное на React Native, компилируется в нативный для платформы язык, не нужно использовать дополнительные промежуточные компоненты (например, Cordova)

    Кордова не является неким "промежуточным компонентом" и тоже компилируется во вполне себе нативный код, внутри которого поднимается виртуальная машина и в ней на том же самом движке исполняется тот же самый JS. Разница лишь в том используются ли нативные или веб компоненты для построения интерфейса. NativeScript, например, позволяет из ограниченно комбинировать.


    компания Drifty Co. решила создать собственную инфраструктуру для написания гибридных приложений, которая будет ориентирована на производительность и будет построена с использованием современных веб-стандартов.
    Проблемы с производительностью — одна из проблем Ionic 2.

    Ну то есть ни производительности, ни стандартов они не достигли :-)


    Ionic 2 блокирует поток и передает управление на JavaScript-код, ожидая его инструкций.

    Тут стоит отметить, что обработчики событий можно вешать "пассивно" и они не будту мешать всяким анимациям исполняться, пока основной поток занят вычислениями.


    Flow умеет вычислять тип переменной, без внесения изменений в код (в отличии от TypeScript)

    TS это тоже умеет.


    По замеру производительности у вас вообще ахтунг. В RN вы замеряли время генерации виртуального дома, а в Ionic — полное время отрисовки. В таблицах у вас разница на порядок. А на графиках всего в пару раз. По размерам приложений тоже ерунда. У меня ipa-шник на кородове получается менее 2 мегабайт. Что я делаю не так?


  1. farwayer
    22.05.2017 20:24
    +1

    Верстка выполняется абсолютными значениями, никаких относительных величин.

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