В этой публикации мы рассматриваем создание таких корпоративных мобильных приложений с использованием различных 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 | |
18.3 Mb | 17.9 Mb | 4.8 Mb | 4.6 Mb | |
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).
В приложении пользователь работает таким образом:
- Для создания новой задачи пользователь выбирает необходимый ему процесс из перечня доступных. После выбора пользователю отображается экран с формой для оформления заявки.
- После создания Заявки пользователь возвращается к списку задач, который представлен на трех табах:
- задачи созданные пользователем;
- задачи, ожидающие решения пользователя;
- задачи, которые назначены на группу людей, где пользователь может взять на себя их решение;
- Если пользователь имеет доступ к Заявке, то для каждой задачи он может детально ознакомиться с информацией в заявке и просмотреть историю ее прохождения.
- Если пользователь принимает решение по заявке, то часть формы Заявки становится доступной для редактирования с опциям для принятия решения.
- При работе с Заявками также доступен поиск по задачам, который выводит результаты по запросу пользователя.
- В приложении реализована функции аутентификации пользователя.
Мобильный клиент, выполняющий описанные выше функции был реализован на каждом из сравниваемых нами фреймворков.
Сравнения готовых приложений
Во время тестирования нашего приложения мы сравнивали скорость рендеринга страницы в зависимости от фреймворка и платформы. Для этого в каждом проекте была создана дополнительная тестовая страница. Данные для отрисовки были сгенерированы в цикле без обращения к серверу. По этим данным создавалось 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 | |
---|---|---|---|---|
5354.6 — 5272.5 | 5663.1 — 5859.5 | 1401.3 — 1750.6 | 7040.3 — 9385.4 | |
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 | |
17.5 Mb | 17.4 Mb | 6.6 Mb | 6 Mb | |
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
- Официальный сайт Ionic Framework
- Статья на Хабрахабр «Ionic: комментарии к мифам после года использования»
- Ionic Creator
- Плагины для Ionic Must-have plugins for Ionic Framework
React Native
- Официальный сайт React Native
- Набор полезных ссылок Awesome React Native
- Анонс React Native (Хабрахабр)
- Tutorial «React Native — одного JS мало»
- In Depth описание React Native и его взаимодействия с мобильной платформой
- Сравнение производительности iOS приложения на swift и React Native
- Песочница для запуска React Native в браузере
- Плагины для React Native
- Using react-devtools with React Native
Сравнение Ionic (2) и React Native
Комментарии (39)
search
18.05.2017 14:49+4Рёбя, немного не в кассу, но хочу поделиться, как я немного обуздал проблему производительности в Ионике 2 на iOS устройствах. На отдельный хабрапост данный текст явно не тянет, так что оставляю его тут в камменте, не пропадать же знаниям.
Так вот. Скроллинг для списков >= 100 элементов неприятно тормозил. Тормоза были двух типов:
- Небольшая задержка при начале скроллинга
- Сам скроллинг работал медленнее в сравнении с нативным
Решения:
- Оказалось что событие
onTouchStart
(да и вообще любое событие) вызывает перерисовку элементов списка, выполняемого директивойngFor
. Для того чтоб этой перерисовки не было можно поместить код сngFor
в отдельный компонент, а к компоненту применитьchangeDetection: ChangeDetectionStrategy.OnPush
. Как показала практика,changeDetection: ChangeDetectionStrategy.OnPush
— довольно неплохое решение для многих проблем производительности в Angular 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. А автору спасибо за статью, всё по делу.
Carduelis
18.05.2017 23:06А по какой причине ангуляр перерисовывает элементы по onTouchStart? Я не пишу на ангуляре, а использую реакт для progressive web apps, и подобные проблемы могут поджидать из-за угла тоже. Если ангуляр перерендеривает список, значит тому есть какая-то логичная причина, а значит, она может быть реализована уже в реакте, или, наоборот, ее придется реализовать рано или поздно (ведь неспроста ж она есть в ангуляре). Да, способ ренедеринга разнится, но проблема рендера списка, особенно большого и в скролле, когда туда добавляются/убавляются элементы на лету — как никогда актуальна.
search
19.05.2017 00:24+1Я прошу прощения, Ангуляр не обязательно перерисовывает весь дом по событиям, но всегда проверяет, не устарел ли элемент. И перерисовывает его в случае необходимости.
Вот тут очень подробно описана работа механизма определения изменений. Если в двух словах, то Ангуляр, используя библиотеку Zone.js, патчит некоторые функции API браузера таким образом, что при вызове этих функций дополнительно выполняется проверка на наличие изменений в дереве компонентов. Классический пример подобного патча — нативная функция
setTimeout()
. Вызов этой функции внутри Angular приложения повлечёт за собой проверку на изменения и перерисовку в случае необходимости. Так же Angular патчит и функциюaddEventListener()
. Таким образом, если навесить на любой элемент событие (например тот жеonTouchStart
), то это событие вызовет механизм проверки/перерисовки дерева компонентов. Попытка скролла в Ионике приводит к неизбежномуonTouchStart
, который вызывает проверку компонентов и тормозит браузер, если компонентов много. Благо, есть способ это отключить.
А вот как Реакт справляется с определением изменений/перерисовкой компонентов мне самому стало интересно :)
vintage
20.05.2017 10:16То же самое будет и в Реакте, если по onTouchStart изменить что-либо в сторе/стейте.
nos
18.05.2017 23:19А Васька слушает, да… продолжает кодить на Appcelerator Titanium.
farwayer
22.05.2017 20:29Как человек, который очень много всего разработал на титаниуме, могу только посочувствовать. Переход на React Native был из разряда «как перестать есть кактус и начать получать удовольствие от кроссплатформенной разработки».
nos
23.05.2017 00:05а парочку ссылок на результаты работ сделанных с удовольствием в app store и google play можно посмотреть?
search
23.05.2017 09:05Интересно, какой вывод об удобстве фреймворка можно сделать глядя на аппстор?
nos
23.05.2017 11:16если на «удобном» фреймворке получаются «неудобные» или медленные приложения, то «удобство» фреймворка можно проигнорировать. :)
nos
23.05.2017 11:21бывают фреймворки где «удобно» лепить простые приложения, но шаг влево или вправо возможен только «костылями» и «извратами». Оценить это можно посмотрев сложные приложения вылизаные и опубликованые в аппстор.
ну и при наличии хорошей наработанной библиотеки компонентов (собственных, а не идущих в пакете) все фреймворки «удобные» по умолчанию.search
23.05.2017 12:58Может для облегчения жизни лучше заюзать готовую библиотеку, пользующуюся поддержкой сообщества? Я так понял, у вас свои наработки уже есть. Вы их публиковали?
nos
23.05.2017 13:12Я писал там выше что мы используем Appcelerator Titanium (но руку на пульсе я держу и за аналогами слежу.). Мне сказали, что ушли с титаниума и стало кодить легче и удобнее. Я удивился ибо пока ничего удобнее и быстрее в разработке не видел и попросил показать результаты в Appstore — интересно сравнить отзывчивость приложений с нативными и титаниумовскими.
я ни в коем случае не планирова устраивать холивар «титаниум против RN или ионик2» просто напомнил что на JS можно писать еще на одном инструменте и он в отличии от описанных выше заточен под корпоративную разработку.
а, публиковать отлаженный инструментарий, который дайт мне преимущество перед конкурентами в корпоративной разработке, публиковать не всегда имеет смысл. плюс публикация это дополнительные затраты (документация, примеры, статьи на хабре и тп)farwayer
25.05.2017 01:47Скажем так: React Native — это тот же титаниум, только лучше. С хорошей производительностью, чистым кодом и без багов, которые годами висят в трекере. Можем пообщаться в личке, если интересно.
nos
25.05.2017 15:19Я этот рекламный меседж я уже понял и выше написал — что порой кажется более удобным — мнее функционально. порой пользоваться отлаженым функционалом по граблям которого ты прошелся более удобным, чем ходить по новым граблям.
Производительность бриджа js-native-js тоже вызывает вопросы — новых технических революций в мире не происходило — скорость бриджа везде примерно одинакова. Или в RN — бридж другой?
В Titanium я могу выбирать где крутить JS loop, в main thread или отдельно — в RN — только в отдельной — итого я по отзывчивости всегда выиграю перейдя в main. то что на меня это наложит отдельные ограничения — я понимаю. но отзывчивость разогнать могу.
Собственно первый пост был именно об этом — покажите приложение в аппсторе написаное на Реакте — с листанием огромных списков с подчиткой на лету, со сложными вьюхами и анимацией — и тогда можно сравнить — что шустрее.
Я могу кинуть ссылок на свои приложения которые в аппсторе на титаниуме и сравним.
А иначе это просто треп… лучше, удобнее…
Например Hooperloop для подключения нативных модулей без писанины на ObjC и Java — при всей глючности более удобный чем кодить модуль отдельно.
farwayer
25.05.2017 01:10Они, в основном, для внутреннего использования были. Сейчас еще парочка на релиз в AppStore/Google Play готовится. Могу дать знать, когда в релиз пойдут.
А «на посмотреть» в строрах сейчас хватает: discord, instagram, airbnb — это из крупных.
https://facebook.github.io/react-native/showcase.htmlnos
25.05.2017 15:25то что монстры накодили огромными командами будучи обязаными кодить на RN — это пример так себе — мы не знаем насколько им там было удобно и сколько раз они подпилили RN под себя для этого.
и сколько раз они изменили свое ТЗ по причине — в RN этого сделать нельзя/геморно/трудно.
мне интересны приложения от человека который утверждает что приложения (не одно) на RN кодить удобнее и удовольствия больше.
проблемы начинаются когда заказчик хочет интерфейс и поведение за пределами коробочных решений фреймворка. вот где такое удобнее делать — в этом вопрос. титаниум постарше — от того он и граблей больше перетоптал.
но суть моего первого поста не меняется — я смотрю на новые инструменты и продолжаю кодить на титаниуме — потому что RN считаю еще не готовым легко «прогнуться»под изменчивый мирпод ТЗ заказчика.
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.
Больше не буду — я и не планировал уходить дальше первого комента :)vintage
25.05.2017 16:53Есть альтернатива в виде Кордовы.
nos
25.05.2017 16:58я использовал кордову когда она была phonegapom с sencha touch — лет 5-6 назад — это вообще не нативные контролы или нативные с бубном. об удовольствии речи нет. производительность слабая, внешний вид — притворяться HTML+CSSом нативными элементами — увольте.
кстати у RN есть репозиторий виджетов которые могут публиковать члены комьюнити чтобы их ставить и юзить потом с пол пинка?
чувствую таки прийдется написать что-то про титаниум и накидать ссылок. у меня например есть под титаниум OpenGL движок кросплатформенный — можно игры 2.5D лабать. 7 интерактивных сказок в аппсторе 5 лет в топ 100 книг без рекламы.vintage
25.05.2017 17:06это вообще не нативные контролы
Кроссплатформенным приложениям и не нужно выглядеть нативными. Мимикрия под натив — это блажь.
sencha touch
Зачем вы эту гадость трогали? :-)
nos
25.05.2017 17:58кросплатформенный титаниум это именно только нативные контролы и мимикрировать не надо.
а sencha — это было требования клиента :(vintage
25.05.2017 21:32Суть не в этом, а в том, что кроссплатформенные приложения обычно стилизуют под общий бренд, иначе придётся делать несколько версий, так как в разных системах разная логика построения интерфейса и взаимодействия с ним.
nos
25.05.2017 22:03это как раз и дело фреймворка чтобы я писал в RN а в Android он был ListView а в iOS UITableView — но и там и там должны быть нативные контролы.
я создал TabGroup и в результате у андроида он сверху а у iOS cнизу. унификация на плечах кросплатформенных фреймворков — это и удобство и головная боль одновременноvintage
25.05.2017 22:23Это работает лишь в простейших случаях, когда контролы мапятся 1-к-1 на разных системах. Это далеко не всегда так.
nos
25.05.2017 23:18например?
vintage
26.05.2017 00:25
ios: два вида таббаров
android: один вид
windows: вообще панорамаnos
26.05.2017 00:26ну и на все три код должен быть одинаков у кроссплатформеного фреймворка. или нет?
vintage
26.05.2017 00:32Тут разные принципы построения приложения. Вы не сможете средствами фреймворка превратить андроидовский таббар в виндовую панораму.
nos
26.05.2017 00:37ios — один вид таббара — верхний — buttonbar — оне не переключает окна
для iOS и Android в Appcelerator код будет идентичен. для винды тот же код будет работать но я не уверен в результате — панорама там будет или еще что
farwayer
25.05.2017 17:56Кривые руки испортят любой хороший инструмент. Это я про блумберг. Действительно ужасно работает. Посмотрите discord — действительно сложное приложение и с точки зрения бизнес-логики, и с точки зрения UI.
Я погонял ваше приложение. Мне кажется, что до нативной скорости работы там далеко.
Отправил вам в личку видео работы приложения на React Native, которое скоро уйдет в релиз. К сожалению, пока не могу выложить его в открытый доступ.
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 мегабайт. Что я делаю не так?
farwayer
22.05.2017 20:24+1Верстка выполняется абсолютными значениями, никаких относительных величин.
Поддержка процентных значений величин была добавлена в React Native в начале апреля. Но, к слову, когда их не было, за все время разработки на RN мне только один раз понадобилось узнать размер экрана. В подавляющем большинстве случаев flexbox позволяет верстать так, что интерфейс будет подстраиваться под любой размер.
nicksyndicate
Одно из преимуществ разработки на RN, это быстрый старт с expo.io