Обновить
8K+
9
Адещенко Кирилл@kaparray

Engineering Manager РСХБ

24,1
Рейтинг
11
Подписчики
Отправить сообщение

Спасибо за честный отзыв — это полезно читать.

Про качество оригинального приложения: да, ревью Apple реально влияет. Не только гайдлайны, но и сам факт того, что приложение проходит проверку, дисциплинирует. Когда публикуешься в обход стора, часть этой дисциплины теряется — и это чувствуется в качестве.

Про «один большой iframe»: это как раз то, о чём написана статья — гибридная модель, где контейнер нативный, а часть экранов на вебе. Face ID при этом работает через нативный слой, не через браузер — поэтому и предлагает включить. Это не случайность, а осознанная архитектура: нативное там, где без него нельзя, веб там, где нужна гибкость обновлений.

То, что это воспринимается как «мини-браузер» — сигнал для нас, что граница между слоями ощущается пользователем. Значит, шов ещё недостаточно незаметный.

Про веб-версию: она есть, и базовые операции там работают. Но баланс, перевод по номеру и оплата по QR в браузере на iOS — это заметно хуже по UX, чем в нативе. Особенно QR: камера через браузер на iPhone работает с ощутимыми ограничениями. Плюс без приложения нет push-уведомлений о транзакциях — а это для многих критично.

Так что веб — это не замена, это дополнение для тех, у кого совсем нет возможности установить приложение.

Полностью согласен — нативное приложение всегда лучше PWA по UX, и мы именно к этому стремимся. Гибридная модель с PWA-слоем внутри нативного контейнера — это не отказ от нативного приложения, а вынужденный компромисс, который позволяет обновлять продукт без пересборки бинарника в условиях, когда тебя могут выкинуть из стора в любой момент. Снаружи — нативное приложение, внутри — часть экранов на вебе. Цель та же: чтобы приложение было, работало и не деградировало после каждого удаления.

Давайте тогда спросим у коллег из Т-Банка, какое соотношение у них между аудиторией PWA и нативного приложения. И заодно уточним, зачем они при «прекрасно работающем PWA» продолжают публиковать в App Store больше фейковых приложений, чем кто-либо другой на рынке.

По API: стабильный контракт на годы — это хорошая цель, но в реальности банковский продукт меняется быстрее, чем любой долгосрочный API-дизайн это выдерживает. Новые регуляторные требования, СБП, изменения в скоринге, новые типы продуктов — всё это ломает «спроектированное один раз». Банки, которые пытались заморозить API, в итоге обрастали слоями адаптеров и версионирования, что сложнее, а не проще.

Важен и контекст: параллельно с мобильной разработкой банк проходит масштабное импортозамещение и цифровую трансформацию — переход от старых монолитов к микросервисной архитектуре. Именно там мы уже проектируем более долгосрочные и стабильные контракты. Но это процесс, а не переключатель — он не происходит мгновенно.

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

Честно — да, баннеры и сторис там тоже есть, спорить не буду. Но они идут в комплекте с переводами, вкладами, кредитами и всем остальным. Вопрос не в том, нравятся ли рекламные механики, а в том, что альтернатива — оставить клиента на приложении, которое вообще не развивается и не поддерживается.

Веб-версия — это не серебряная пуля. Вот конкретные вещи, которые нативное приложение даёт там, где браузер не справляется:

— Push-уведомления на iOS в браузере до сих пор работают хуже, чем в нативе, особенно на старых версиях системы, а наша аудитория далеко не всегда на последней iOS.

— Биометрия (Face ID / Touch ID) в вебе через WebAuthn работает, но с ощутимыми ограничениями по сравнению с нативным Keychain.

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

— Доступ к камере для сканирования документов, QR-кодов, чеков — в браузере есть, но с заметно худшим UX.

— Доступ к контактам для переводов по номеру телефона — в браузере недоступен совсем.

— Наконец, просто конверсия: пользователь, у которого приложение на главном экране, возвращается чаще, чем тот, кто должен каждый раз вспоминать адрес сайта.

Мы не спорим, что гибридная модель с PWA — это во многом вынужденное решение. Но полностью уйти в веб и потерять всё перечисленное — это не упрощение, а деградация продукта для конкретной аудитории.

Окирпичивание — это не про баннеры. Это единственный доступный инструмент принудительной миграции в условиях, когда у тебя нет доступа к push-уведомлениям, нет возможности обновить бинарник и нет App Store. Все «мягкие» каналы — SMS, email, баннеры в интернет-банке — давали конверсию в разы ниже.

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

Не совсем так, и статья как раз подробно объясняет почему.

«Добавить элемент в массив» работает только для продуктов, которые укладываются в существующую архитектуру отображения. Но в статье речь о другом: старое приложение — это замороженный бинарник, который вообще нельзя обновить. Никакой серверный ответ не добавит в него новый клиентский путь, инвестиционный сервис или обновлённый бизнес-процесс оформления кредита — всё это живёт во фронте, а не в данных с бэкенда.

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

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

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

По веб-версии: мы её развиваем, и PWA, и полный интернет-клиент живы. Но мы — банк для физлиц, и распределение аудитории жёсткое: подавляющее большинство пользователей живёт в мобильном приложении, веб-каналы — это важная, но маленькая доля.

Про блокировку и поход в отделение — понимаю фрустрацию. Это не продуктовая прихоть, а требования по безопасности. Над выбором из более удобных способов восстановления работаем.

Да, ваше наблюдение верное — подход не новый, крупные банки переходили на web-модули внутри контейнера в разные годы. Мы полноценно живём в этой архитектуре с начала 2024 года, и большинство правок интерфейса действительно едет без выкатки клиента — эффект «куски меняются сами» ровно отсюда. Миграция на новое приложение, про которую статья, нужна в тех случаях, когда изменения выходят за рамки контейнера — меняется схема API, появляются новые нативные компоненты.

Хороший вопрос, тут важно уточнить, что селективность — это не «оставили часть клиентов на старом приложении навсегда», а перенос их миграции в другой канал.

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

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

Справедливо, санкции тут не первопричина, а ускоритель. К модульности рано или поздно приходят все, у кого продукт активно развивается — просто потому что монолит не успевает за бизнесом.

Интересно, что вы пошли в нативную модульность с пересборкой через админку. Мы в итоге выбрали web-модули внутри контейнера — у банка специфика в том, что регуляторных и продуктовых изменений много, и переиспользовать одну и ту же логику между iOS, Android и интернет клиенте оказалось дешевле, чем поддерживать три нативные реализации. Но в ритейле, где UX-требования к скорости и анимациям выше, ваш выбор выглядит логичным.

Добрый день! Спасибо за комментарий. Отвечаю на ваши пункты:
1) спасибо
2) Думаю это вопрос "вкусовщины". Я считаю что интерфейс должен быть явно выделен. То есть название должно быть i_name_of_class.dart и имя класса INameOfClass. Это позволяет более явно отделить интерфейсы от реализации.
3) Моё мнение "всегда нужно исходить из бизнес потребностей".
4) Согласен. Вы уже мигрировали свой проект на dart 3? Расскажите опыт.

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

Утечек памяти нет. По поводу переполнения могу сказать одно, сделал эксперимент с открытием 100 экранов в дереве и всё работало прекрасно!

Спасибо за фидбэк, уже есть в задумке написать туториал по сложной навигации. Он на самом деле вписывается в концепцию которую я описал в разделе “Best practice ”, так как я лично реализовал в этой парадигме навигацию с табами, фрагментами и тд

Согласен, но именно вызов метода pushNamed декларативен, так как знание о переходе скрыто от потребителя. То есть знание каким образом, как и куда реализовано в другом месте.
По поводу Navigator 2.0 я общался с @chunhtai пару месяцев назад и предлагал свою помощь. Точные сроки выхода нового принципа навигации никто не может назвать, но вдохновлялись Angular.
Я не буду с вами спорить. Советую более детально изучить Фреймворк. Видно что вы верхнеуровневого глянули на исходники и не видите всей картины.

Просто просьба не вводить людей в заблуждение:
1) У Flutter нет 3х параллельных деревьев! Это просто вложенные друг в друга абстракции. Созданы для разделения обязанностей между собой.
2) Где что храниться?
— Кол флу такой что создаётся StatefulWidget у него BuildOwner вызывает метод createElement и передаёт туда ссылку на виджет с помощью this.
Дальше в кострукторе StatefulElement вызывает метод createState у виджета.
Дальше в State прикидывает себя и виджет при помощи всё того же this ``` _state._element = this;``` и ``` _state._widget = widget;```.

Таким образом:
StatefulElement знает о widget и state и о своём родителе.
State знает о widget и element.
StatefuWidget — хранит ключ (Key).

3) Доступа к RenderObjectWidgets RenderObjectElement у меня нет.
То что вы привели — это просто абстракции, я говорил про конкретный пример.
Например _CupertinoDialogRenderWidget()
Я реализовывал полностью на канве свой StatefulWidget и прекрасно знаю как это всё устроено.

4) ```Глупо их просто разделять, так как вообще Element это одно из филдов в abstract class Widget.```
Тут согласен, имел ввиду конечно же State.

4) и опять к 3м параллельным деревьям
То что вы привели пример c абстрактными классами, это забавно. Изучите более детально.

Если у вас есть желание то можете со мной связаться в телеграм(kaparray) и я более детально вам скажу куда копать.

Хорошего дня)


Это больше похоже на элемент + виджет.

Ответ:
виджет — описание элемента. Смотрим исходники и видим:
«Widget — Describes the configuration for an [Element].»
Виджеты были сделаны только для того чтобы абстрагировать программистов от жизненного цикла и канаваса. Глупо их просто разделять, так как вообще Element это одно из филдов в abstract class Widget.



Но даже без него связка а-ля элемент + виджет — это «дорогие» и «тяжелые» объекты.

Ответ: С чего вы это взяли? Откуда у вас такие данные? Можно больше данных?


Как раз подобного пытались избежать во Flutter, разделив деревья на 3 параллельных уровня.

Ответ: нет никаких 3-х параллельных деревьев.
Это все статьи сделаны для более простого понимания устройства фреймворка.
Тем более Element есть только у StatefulWidget.

А вот если посмотреть то:
StatefulWidget — это виджет, у него есть State.
В State храниться Element.
BuildContext — это на самом деле и есть наш Element, но в нём при помощи приватных методов скрыта многая функциональность.

А где же RenderObject???

Да вот на самом деле есть ещё RenderObjectWidget и RenderObjectElement. У меня как у программиста нет к ним доступа, так как это приватные классы.

Так вот эти RenderObjectWidget — это наследник Widget, так же как и StatefulWidget.

А вот RenderObject один из филдов в RenderObjectElement. У каждого наследника RenderObject переопределяется метод paint который и вызывает рисование на Canvas.

У Canvas есть native вызовы, которые стучатся в canvas.cc в Flutter Engine.

Так что рассказы про то что в Flutter 3 параллельных дерева — это полный буллщит.
Дерево — это на самом деле не больше чем один большой объект в который вложены другие. там сразу и widget и element и render object.
это вы можете проверить просто вызвав метод debugDumpApp()


А еще в дополнение к этой схеме, слышал вроде бы RN по мосту гоняет данные в JSON формате и при увеличении количества данных, мост начинает проседать.

Ответ: в точку!!!

1

Информация

В рейтинге
337-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность