Интервью
Валентин Калинин (Head of mobile в «Лиге Ставок»): Flutter – идеальное решение
О том, почему была выбрана именно Flutter-платформа, какие в ней плюсы и минусы, рассказал Валентин Калинин Head of mobile, Team lead of outstanding development team в компании «Лига Ставок».
Приложение «Лига Ставок» является одним из крупнейших в России Flutter-продуктом: каждый день в нем появляются более десяти тысяч спортивных событий, и генерируются свыше семи миллионов исходов пари. О том, почему была выбрана именно Flutter-платформа, какие в ней плюсы и минусы, рассказал Валентин Калинин Head of mobile, Team lead of outstanding development team в компании «Лига Ставок».
В Лиге до Flutter была нативная разработка – отдельно iOS, отдельно Android. В 2017 и 2018 году был самый расцвет нативной разработки, нормальные красивые хорошие приложения. Почему именно в этот период ты начал смотреть в сторону кроссплатформы?
В 2015 году у меня созрело желание делать свои стартапы. Я смотрел в сторону кроссплатформы, которая сможет содержать в себе web, начал делать Progressive Web Apps, а нативную часть делали на Cordova. У нас был сервис видеозвонков – этакий Skype с синхронным переводом. Мы делали многоканальный звук, и переводчики могли переключать каналы, говорить в разные уши людям по разным каналам.
Web на тот момент был очень сырой, и на телефоне при запуске приложения оно сразу потребляло половину ресурсов. Видеопоток включался, и его невозможно было никак забрать обратно. Приложение переставало нормально работать. До включения видео все было вполне прилично, но после становилось совсем грустно. И тогда я занялся вебом, несколько лет поработал как web-разработчик с Angular, React, Polymer. А зимой 2017-го мне попался Flutter. Я попробовал перевести парочку своих проектов на Flutter, сделал iOS и Android приложения на Angular и Dart на общем коде. Был пакет кода, который шарился между вебом и нативом. Все, что мне нужно делать на платформах и в вебе, меня вполне устроило. Все, что я хочу сделать, я могу. И пошел искать компанию, где потребуются такие услуги…Так я и Flutter появились в Лиге Ставок.
Дальше основная проблема была в сроках, потому что была небольшая аутстафф команда, которая сидела и пилила приложение. Несколько месяцев мы попробовали. Я взял нескольких сотрудников специально под Flutter. За пару месяцев мы сделали полунатив, где один из элементов был написан на Flutter. Баги UI начали расти как снежный ком, команда не успевала их закрывать. И мы решили все переписать на Flutter, потому что сроки совсем поджимали, а писать дважды – не хватало команды из 4-5 человек. Всего в самом проекте больше сотни бизнес-кейсов. Каждый из них нужно было хорошо обработать, нельзя ничего зафакапить, и выкидывать особо нечего. Мы начали писать все сначала в таком режиме: критические бизнес-части находятся в нативе, real-time данные – в WebSocket, а вся бизнес-логика – уже в Dart на общем коде.
Мы успешно защитили перед руководством и запустили альфа-версию. Начали убирать лишние нативные части, зависимости от нативных сокетов, переписали все полностью на Dart. К лету мы были готовы, и в сентябре вышли в открытую бету. При этом оставался еще и текущий клиент, который поддерживали подрядчики. Параллельно люди начали переходить на новое приложение, смотреть, пробовать.
Это в 2019 году?
Сентябрь 2019 года. В сентябре мы запустили открытое бета-тестирование. И в течение нескольких месяцев все продолжалось в таком формате– open beta, релизы параллельно нескольких приложений.
Под Новый год Android-команда не смогла запустить нативное приложение на Android 10, который тогда вышел. Подрядчики не смогли быстро понять, в чем проблема. Так мы экстренно вышли в продакшн. Заменили нативное приложение на Android. И через какое-то время туда же отправили iOS.
Началась большая миграция пользователей. В базе Лиги Ставок несколько миллионов зарегистрированных пользователей, поэтому процесс растянулся. Миграция идет до сих пор. Скоро планируем закрыть старые нативные приложения. Осталось 100-200 человек, которые не обновились и периодически заходят, но основная масса людей уже переехала на Flutter-приложение.
Как в компании, у которой уже есть приложения и определенная команда, начать делать новое на платформе, на которой еще никто не умел работать? Что надо сказать людям, чтобы они поверили в это?
Во-первых, надо сказать: «Я все сделаю». Обязательно гарантировать результат.
Во-вторых, объяснить, что получает компания. Если бы мы продолжали развивать нативные компетенции внутри компании, это был бы очень дорогой проект. Как минимум два тимлида – iOS, Android, две команды, два QA. И очень проблематично это все было бы в тех условиях, которые у нас были. Приложение Лиги Ставок очень большое с точки зрения бизнеса и нагрузки. Просто у нас не было других выходов.
Изначально рассматривался вариант с React Native и Flutter. Тогда как раз вышла статья Airbnb, как они на него плюются и уходят. Это помогло убедить руководство компании попробовать Flutter.
Были еще какие-то альтернативы, которые рассматривались всерьез?
Для меня – не было, потому что я изначально подобрал Flutter под себя и свои задачи. Я понял, что в текущей кроссплатформе, которая дала бы мне возможность делать не только iOS, Android, но еще и web, мне нужен был общий код, который обязательно мог бы иметь выхлоп в web. Все пет-проекты, которые я делал, были кроссплатформенные. У меня не было возможности нанимать команду, которая отдельно бы пилила web. Поэтому задача была именно подобрать нужный инструмент. Здесь подходит и React Native, и Flutter. Но наличие бриджа у React Native ставит крест вообще на технологии как таковой, потому что скорость отдачи, отзывчивость… получается такое техническое решение уже с заведомым…
Ухудшением.
…Недостатком очень серьезным. Технически оно было гораздо хуже. Плюс Flutter очень активно развивался. Мне понравился Dart как язык, потому что после плюсов я перешел на него за неделю. В дальнейшем опыт работы команды с Flutter показал, что нативщики Kotlin, React Native разработчики, веб-разработчики, очень легко переходят на Dart. С языком у нас никогда не было проблем, мы очень быстро обучились и начали писать на Dart уже в команде.
Сейчас в вашей команде больше 20 человек. Мне кажется, любая кроссплатформа – это всегда в той или иной мере компромисс. Если бы вы в тот момент начали пилить на тех же 20-ти разработчиках нативные приложения, вы бы за это же время сделали нормальные нативные приложения и под iOS, и под Android…
Нет, не сделали бы никак. А мы сейчас релизим четыре приложения параллельно на общей кодовой базе. Имея общий код, мы сокращаем расходы на тестирование, интеграционные тесты, дизайн-систему. Во многих компаниях пытаются писать две дизайн-системы под iOS и Android, и как-то выравнивать их между собой.
Чем еще привлекательна разработка под Flutter? Этот инструмент думает о программисте и помогает ему писать качественный код, который быстро работает. Он совершенно не уступает нативу. Скажу больше, SwiftUI и Compose пошли по пути Flutter, и Compose копирует многие вещи из Flutter. Декларативные разработка и верстка, которую Flutter предложил еще в альфа-версиях в 2017-2018 годах, на нативные платформы только приходит. Причем, если у SwiftUI обязательное требование – наличие iOS 14, а Compose в продакшн не многие рискуют запускать, то релиз Flutter состоялся 4 декабря 2019 года. И целый год уже можно пользоваться продакшн-версией достойного качества.
Если говорить о качестве, ты видишь какие-то компромиссы, проблемы в разработке, инструментах, поддержке?
Я могу рассказать про плюсы по сравнению с нативной разработкой. Мы уже довольно долго не ведем разработку с эмуляторами. Если нужно сделать бизнес-задачу, у нас есть трайбы. Для людей, которые не взаимодействовали раньше с мобильной разработкой, Android и Xcode очень сложны. Поэтому у нас есть такая штучка, называется «hover». Это написанный раннер на Go, который позволяет запускать Flutter-приложение на десктопе. Писать код, бизнес-код, бизнес-функции, показывать юзерам превью можно полностью на десктопе. Скорость запуска не сравнима с эмулятором. Даже сам эмулятор стартует дольше, чем полностью рабочее приложение на Flutter, которое можно запустить под десктоп. Плюс, мы уже смотрим в сторону mobile web.
Именно с точки зрения инструментов Flutter кажется вполне себе зрелым решением, нет ничего такого, чего бы не было в нативе. Всегда можно переключиться в нативный проект – Android или Xcode – и все запустить, посмотреть, наладить, точно так же использовать Crashlytics, смотреть все отчеты. Это все работает.
Основная фишка, которая всех привлекала – Hot-reload. Когда ты уже в запущенной программе меняешь код, просто делаешь Hot-reload, одна секунда, и у тебя обновленный код, именно на той страничке, где ты находишься. Ничего не надо перезапускать, ничего не надо перестартовывать. Скорость разработки сильно выросла по сравнению с нативом.
Вроде Android Studio и Kotlin так умеет?
Она в каких-то из последних версий научилась делать Hot-reload, но он не такой крутой, как у Flutter. У нас есть Hot-reload и Hot-restart, которыми моментально можно перестартовать целиком приложение или перестроить конкретный экранчик.
Сейчас как одна из главных альтернатив Flutter рассматривается Kotlin Multiplatform Mobile. Вы не смотрели в эту сторону?
Я считаю, что основное преимущество Flutter – его кроссплатформенный UI, именно декларативный интерфейс. Dart позволяет Лиге Ставок реализовать полностью практически всю логику. У нас на нативе 1% просто обвязки, которая работает с пушами. Flutter как раз закрывает UI-проблемы, унифицирует написание фронтенд-кода, а Kotlin Multiplatform предлагает в качестве написания общих модулей на Kotlin.
Flutter быстро развивается. Вышла версия, которая позволяет делать прямые вызовы сишных библиотек, то есть в Kotlin или Swift можно просто брать готовый ffmpeg и использовать его прямо в Dart-коде. Kotlin Multiplatform выгоден для тех, кто хорошо знает Kotlin, у кого есть уже написанная кодовая база на Kotlin, и ее хотят пошарить. Но опять же, без Compose, пока не будет такого же кроссплатформенного UI, это – половинчатое решение.
У вас есть какая-то нативная часть, которая реализует пуши. То есть все-таки какой-то функционал недостаточен?
Нет. Не недостаточно. Сам Flutter (его подход) – это обычное нативное приложение, обычный раннер, в котором предоставляется только canvas, то есть приложение для Flutter может…рисовать на любом холсте. И Android Activity предоставляет этот canvas для отрисовки, но все функции, которые работают с биометрией, видеокамерой, видеоплеер – это все нативные элементы, которые просто стримят данные из натива во Flutter. Так как там нативные платформенные каналы, которые обмениваются данными без преобразования, по сути, Flutter компилится ahead-of-time тоже в нативное приложение, из-за чего нет проблем с производительностью.
Flutter – это фреймворк, который работает поверх нативного приложения и компилируется именно как нативное приложение. Это не React Native, который представляет собой все-таки JVM машину, которая перекидывает в натив свои данные по каналам, получает их обратно и преобразовывает опять в JVM. Этот бридж как раз отсутствует. То есть Flutter, по сути, – просто библиотека для отрисовки красивых юзер-интерфейсов в декларативном стиле. При этом мы имеем полностью все возможности платформы, которые только есть.
Мы также запускались и на Linux, и на CentOS, т.е. на macOS просто на нативном без каверов и прочих вещей. Его можно запустить везде, где есть платформенная интеграция в виде canvas. Это движок, который занимается отрисовкой всего на С++.
Со стороны кажется, что все-таки Google немного притормозил с Flutter. У вас нет такого ощущения?
Flutter вышел в продакшн год назад. И все движения, которые сейчас есть, поступательные. Их основные усилия сейчас направлены на Flutter for Web и качественную поддержку. С точки зрения именно экосистемы между iOS, между Compose с Kotlin, например, и Flutter с Dart, то тут выбор за конкретными людьми, которые приходят с веба. Они чаще смотрят на Dart, потому что сам язык ближе и к Java, к JavaScript, он легко понимаем, подходит как язык общего назначения. А те, кто писали в нативе, больше выбирают Compose. Просто выбираешь инструмент, который решает одну и ту же задачу. То же самое SwiftUI – декларативный интерфейс, а дальше – выбор инструментов.
Если начинающему мобильному разработчику идти во Flutter, с чего начать?
Все Android-разработчики (у меня довольно большое количество знакомых Android-разработчиков, которые постепенно сейчас смотрят и пробуют что-то делать на Flutter) говорят, что у Flutter одна из лучших документаций в мире. Им очень не хватает такой на Android. Есть и Codelabs, есть просто замечательный Dart Language Tour. Все языковые особенности описаны, все можно спокойно потыкать. Есть Dart Playground, где можно тут же написать код, исполнить его, посмотреть, как все это работает в браузере. Не надо ничего устанавливать.
На сайте Flutter есть примеры, которые отрисовываются тут же в виде эмулятора в браузере, и меняя что-то в коде, можно спокойно увидеть результат. Flutter демократизирует разработку. Не нужно знать какого-то сильного хардкора в нативной разработке, знакомиться со сложным инструментарием Xcode, разбираться с XML-файлами или сторибордами. Можно взять буквально две команды, и приложение уже запустилось.
С точки зрения автоматизации инструментов все хорошо, потому что работает непосредственно Xcode и Android Studio. Они собирают проекты, а Flutter только управляет этим всем делом. Я работаю в VSCode. Есть предиктивный ввод, он помогает, подсказывает с помощью машинного обучения, и само написание кода на Flutter упрощается по сравнению с нативом.
В России есть уже какое-то сообщество, потому что я читаю все время Surf, Wrike, по-моему, даже конференцию буквально через несколько дней проводит по Dart. Какой-то хаб, центр разработки на Flutter?
Wrike много лет уже использует Dart для написания своего основного продукта, это их система управления задачами, и она пишется именно на Dart. У них был свой канал, посвященный Dart-разработке. В 2018 году в нем было 200-300 человек. С появлением Flutter на радарах у обычных людей, набралось больше 5000 участников в комьюнити, в основном в Telegram.
Современный мир требует современных решений. Flutter хорошо принимается. Очень много людей уже начали писать и выводить на рынок свои приложения. Неплохо принимают Flutter именно в мире Android-разработки. iOS-разработчики смотрят с чуть большим скепсисом, по причине своей более снобистской позиции вообще к каким-либо другим решениям, кроме iOS. Но я думаю, со временем это изменится, с выходом SwiftUI люди ближе познакомятся с декларативным подходом, и Flutter в том числе.
Наша команда делится экспертизой, своим опытом разработки на крупном проекте. Мы завели блог на Хабре. В сентябре сделали митап с Яндексом в гибридном формате, пригласили спикеров и гостей в офис Лиги, отлично неформально пообщались! В начале декабря «Лига Ставок» провела первый в России онлайн-хакатон по Flutter – было более 30 команд от Белгорода до Томска, от Бухары до Варшавы, от Грозного до Санкт-Петербурга, от Москвы до Одессы. Спасибо участникам, это было очень интересно. Победители получили денежный приз, и мы нашли ребят, которыми можем усилить свою инхаус команду.
Приложение «Лиги Ставок» очень нагруженное, несколько миллионов пользователей. Есть особенности работы клиентских приложений?
Возникают проблемы с китайскими Android-устройствами, которые не имеют сервисов Google. Для пользователей это бывает проблематично, особенно если у них нет предустановленных сервисов.
По сравнению с нативным приложением, которое у нас было, и в котором crash rate был 90%, у нас ниже 99% ничего не падает, таких ситуаций мы не допускаем. Может сначала было пару раз по неопытности, когда внедряли плагин, который должен работать на iOS и Android, а на какой-то из платформ он отказывался функционировать. Сами плагины могли вносить сбои.
Flutter очень надежен с точки зрения крэшей. Плюс он интегрируется с Firebase Crashlytics, мы еще используем AppDynamics для технического мониторинга. Везде все хорошо интегрируется. Сейчас практически каждый производитель какого-то софта старается сделать свой SDK на Dart и предоставить возможность интегрировать его во Flutter. Либо, как это делается в Firebase, – у них написаны плагины, которые предоставляют Flutter Dart Class, который через нативные каналы перекидывает вызовы в нативные SDK. Любой нативный код можно подключить в виде класса во Flutter с помощью обертки.
Например, в AppGallery, в каких-нибудь китайских магазинах в отсутствии сервисов Google все будет более-менее хорошо работать, если не касаться специфических вещей, вроде оплат?
Проблем не возникает. Практически любую систему можно спокойно интегрировать через платформенный код.
Сейчас все усилия направлены на web-версию. Что-нибудь еще изнутри расскажете о будущем Flutter, Dart?
Flutter активно набирает популярность в GitHub, борется с Kotlin по популярности.
Fuchsia использует Flutter как свой фронтенд. Все смарт-дисплеи, которые будут появляться у нас с приходом 5G – это и тонкие терминалы, и различные Google Auto, и AR, VR, и любые умные устройства с экранами – для них мы можем создавать кроссплатформенные приложения. Поэтому я думаю, что у Flutter большие перспективы в будущих девайсах, где потребуется и голосовая, и визуальная интеграция. Google сейчас отходит от Voice Only общения с устройствами, визуальная составляющая человеку очень важна, поэтому новые устройства будут вместе с дисплеями и с АI. Кажется, Flutter – идеальное решение для этих систем.
Как в кино: ничего не будет. Ни кино, ни театра, ни книг, ни газет – один сплошной Flutter.
Будет, будет много разных вариантов делать декларативный интерфейс: на SwiftUI, на Compose, на Flutter.