Комментарии 41

Рёбя, немного не в кассу, но хочу поделиться, как я немного обуздал проблему производительности в Ионике 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. А автору спасибо за статью, всё по делу.

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

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


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


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

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

Кстати, сильно страдал от использования cordova-plugin-advanced-http. Точнее от невозможности использовать стандартный ангуляровский HttpClient и невозможность запускать и отлаживать своё приложение в браузере. По такому случаю была написана вот эта либа https://github.com/sneas/ionic-native-http-connection-backend. Она предоставляет адаптер от cordova-plugin-advanced-http для HttpClient когда это необходимо и возможно.

Да, было бы интересно почитать сравнение именно Native-like инструментов, я на сегодняшний день слышал о (помимо упомянутых):
tabrisjs
fusetools
weex-project.io
А Васька слушает, да… продолжает кодить на Appcelerator Titanium.
Как человек, который очень много всего разработал на титаниуме, могу только посочувствовать. Переход на React Native был из разряда «как перестать есть кактус и начать получать удовольствие от кроссплатформенной разработки».
а парочку ссылок на результаты работ сделанных с удовольствием в app store и google play можно посмотреть?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

но суть моего первого поста не меняется — я смотрю на новые инструменты и продолжаю кодить на титаниуме — потому что RN считаю еще не готовым легко «прогнуться» под изменчивый мир под ТЗ заказчика.
Сходил по ссылке посмотрел 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.

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

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

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

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


sencha touch

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

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

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

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

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

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

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

image


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

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

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

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

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

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


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

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

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

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

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


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

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


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

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


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

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


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

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


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

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

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