Comments 41
Рёбя, немного не в кассу, но хочу поделиться, как я немного обуздал проблему производительности в Ионике 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. А автору спасибо за статью, всё по делу.
Я прошу прощения, Ангуляр не обязательно перерисовывает весь дом по событиям, но всегда проверяет, не устарел ли элемент. И перерисовывает его в случае необходимости.
Вот тут очень подробно описана работа механизма определения изменений. Если в двух словах, то Ангуляр, используя библиотеку Zone.js, патчит некоторые функции API браузера таким образом, что при вызове этих функций дополнительно выполняется проверка на наличие изменений в дереве компонентов. Классический пример подобного патча — нативная функция setTimeout()
. Вызов этой функции внутри Angular приложения повлечёт за собой проверку на изменения и перерисовку в случае необходимости. Так же Angular патчит и функцию addEventListener()
. Таким образом, если навесить на любой элемент событие (например тот же onTouchStart
), то это событие вызовет механизм проверки/перерисовки дерева компонентов. Попытка скролла в Ионике приводит к неизбежному onTouchStart
, который вызывает проверку компонентов и тормозит браузер, если компонентов много. Благо, есть способ это отключить.
А вот как Реакт справляется с определением изменений/перерисовкой компонентов мне самому стало интересно :)
Кстати, сильно страдал от использования cordova-plugin-advanced-http. Точнее от невозможности использовать стандартный ангуляровский HttpClient и невозможность запускать и отлаживать своё приложение в браузере. По такому случаю была написана вот эта либа https://github.com/sneas/ionic-native-http-connection-backend. Она предоставляет адаптер от cordova-plugin-advanced-http для HttpClient когда это необходимо и возможно.
Интересно, какой вывод об удобстве фреймворка можно сделать глядя на аппстор?
ну и при наличии хорошей наработанной библиотеки компонентов (собственных, а не идущих в пакете) все фреймворки «удобные» по умолчанию.
Может для облегчения жизни лучше заюзать готовую библиотеку, пользующуюся поддержкой сообщества? Я так понял, у вас свои наработки уже есть. Вы их публиковали?
я ни в коем случае не планирова устраивать холивар «титаниум против RN или ионик2» просто напомнил что на JS можно писать еще на одном инструменте и он в отличии от описанных выше заточен под корпоративную разработку.
а, публиковать отлаженный инструментарий, который дайт мне преимущество перед конкурентами в корпоративной разработке, публиковать не всегда имеет смысл. плюс публикация это дополнительные затраты (документация, примеры, статьи на хабре и тп)
Производительность бриджа js-native-js тоже вызывает вопросы — новых технических революций в мире не происходило — скорость бриджа везде примерно одинакова. Или в RN — бридж другой?
В Titanium я могу выбирать где крутить JS loop, в main thread или отдельно — в RN — только в отдельной — итого я по отзывчивости всегда выиграю перейдя в main. то что на меня это наложит отдельные ограничения — я понимаю. но отзывчивость разогнать могу.
Собственно первый пост был именно об этом — покажите приложение в аппсторе написаное на Реакте — с листанием огромных списков с подчиткой на лету, со сложными вьюхами и анимацией — и тогда можно сравнить — что шустрее.
Я могу кинуть ссылок на свои приложения которые в аппсторе на титаниуме и сравним.
А иначе это просто треп… лучше, удобнее…
Например Hooperloop для подключения нативных модулей без писанины на ObjC и Java — при всей глючности более удобный чем кодить модуль отдельно.
и сколько раз они изменили свое ТЗ по причине — в RN этого сделать нельзя/геморно/трудно.
мне интересны приложения от человека который утверждает что приложения (не одно) на RN кодить удобнее и удовольствия больше.
проблемы начинаются когда заказчик хочет интерфейс и поведение за пределами коробочных решений фреймворка. вот где такое удобнее делать — в этом вопрос. титаниум постарше — от того он и граблей больше перетоптал.
но суть моего первого поста не меняется — я смотрю на новые инструменты и продолжаю кодить на титаниуме — потому что RN считаю еще не готовым легко «прогнуться»
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.
Больше не буду — я и не планировал уходить дальше первого комента :)
Есть альтернатива в виде Кордовы.
кстати у RN есть репозиторий виджетов которые могут публиковать члены комьюнити чтобы их ставить и юзить потом с пол пинка?
чувствую таки прийдется написать что-то про титаниум и накидать ссылок. у меня например есть под титаниум OpenGL движок кросплатформенный — можно игры 2.5D лабать. 7 интерактивных сказок в аппсторе 5 лет в топ 100 книг без рекламы.
это вообще не нативные контролы
Кроссплатформенным приложениям и не нужно выглядеть нативными. Мимикрия под натив — это блажь.
sencha touch
Зачем вы эту гадость трогали? :-)
а sencha — это было требования клиента :(
Суть не в этом, а в том, что кроссплатформенные приложения обычно стилизуют под общий бренд, иначе придётся делать несколько версий, так как в разных системах разная логика построения интерфейса и взаимодействия с ним.
я создал TabGroup и в результате у андроида он сверху а у iOS cнизу. унификация на плечах кросплатформенных фреймворков — это и удобство и головная боль одновременно
Это работает лишь в простейших случаях, когда контролы мапятся 1-к-1 на разных системах. Это далеко не всегда так.
ios: два вида таббаров
android: один вид
windows: вообще панорама
Тут разные принципы построения приложения. Вы не сможете средствами фреймворка превратить андроидовский таббар в виндовую панораму.
От корпоративного мобильного приложения не требуется сверх-большая производительность (такая как в приложениях с миллионами пользователей от Facebook)
Число инсталляций как-то влияет на требования к отзывчивости приложений?
Ввиду того, что приложение, написанное на React Native, компилируется в нативный для платформы язык, не нужно использовать дополнительные промежуточные компоненты (например, Cordova)
Кордова не является неким "промежуточным компонентом" и тоже компилируется во вполне себе нативный код, внутри которого поднимается виртуальная машина и в ней на том же самом движке исполняется тот же самый JS. Разница лишь в том используются ли нативные или веб компоненты для построения интерфейса. NativeScript, например, позволяет из ограниченно комбинировать.
компания Drifty Co. решила создать собственную инфраструктуру для написания гибридных приложений, которая будет ориентирована на производительность и будет построена с использованием современных веб-стандартов.
Проблемы с производительностью — одна из проблем Ionic 2.
Ну то есть ни производительности, ни стандартов они не достигли :-)
Ionic 2 блокирует поток и передает управление на JavaScript-код, ожидая его инструкций.
Тут стоит отметить, что обработчики событий можно вешать "пассивно" и они не будту мешать всяким анимациям исполняться, пока основной поток занят вычислениями.
Flow умеет вычислять тип переменной, без внесения изменений в код (в отличии от TypeScript)
TS это тоже умеет.
По замеру производительности у вас вообще ахтунг. В RN вы замеряли время генерации виртуального дома, а в Ionic — полное время отрисовки. В таблицах у вас разница на порядок. А на графиках всего в пару раз. По размерам приложений тоже ерунда. У меня ipa-шник на кородове получается менее 2 мегабайт. Что я делаю не так?
Ionic 2 vs React Native: сравнение фреймворков для создания корпоративных мобильных приложений