Итак, здравствуйте! Меня зовут Никита Синявин, я ведущий Flutter-разработчик в компании BetBoom. Я автор личного блога Boltology Tech, а также лидер сообщества мобильных разработчиков Mobile Assembly в Калининграде.
20 декабря 2023 года я опубликовал статью на Хабр (по совместительству мою первую статью) - Just DUIT - первый взгляд на server-driven UI фреймворк для Flutter, в которой я познакомил читателей с первой версией Duit.
С тех пор прошло достаточно много времени, работа над проектом не останавливалась, но зачастую двигалась скачкообразным темпом: появлялись новые виджеты и фичи, проверялись смелые гипотезы, велась работа по “популяризации” фреймворка среди разработчиков.
Сегодня у Duit день рождения, а потому я хочу провести для вас небольшой экскурс в историю его развития. Уже интересно? Пристегиваемся и погнали!
С чего все начиналось
Вначале было приложение, и это приложение было на React Native… Это не шутка, ведь в BetBoom я пришел в качестве React Native разработчика. Но в рамках проекта по глобальному редизайну мы смогли убедить бизнес мигрировать на Flutter и по большей части не ошиблись с выбором. Прочитать подробнее об этом можно в этой статье.
Единственной болезненной темой стала потеря CodePush, через который мы доставляли наибольший процент обновлений. В связи с этим команда начала рассмотрение вариантов того, как мы могли бы с этим разобраться. Мы обсуждали и ShoreBird (который был слишком сырым и выглядел ненадежно), и BDUI (библиотеки для реализации которого были совершенно не функциональны, а DivKit для Flutter еще не было). По итогу, сошлись на том, что обновлять приложения мы будет по старинке - через сторы. Но я не был готов смириться с таким положением дел и концепция BDUI поглотила мои мысли.
Изначально Duit планировался как библиотека, способная отрисовать на экране устройства рекламные баннеры, описание которых приходит с бекенда, но при этом сделать их намного более интерактивными: добавить кнопки для взаимодействия, придать динамики UI и тд. Ничего сверхъестественного, проект на пару недель, так подумал я.
После месяца запойной работы я наконец-то оторвал глаза от клавиатуры, посмотрел в монитор и увидел, что я научился получать макет с бекенда и отрисовывать цветные прямоугольники разного размера, размещаться их в колонку, строку или в стеке, а вдобавок к ним еще и кнопки с текстом рисовать. И тут понеслось…
Как менялся Duit
В первой версии фреймворка было реализовано всего 16 виджетов. Достаточно скромный набор. Спустя год их количество увеличилось до 38. Число увеличилось на порядок, но тем не менее, осталось все таким же не представительным. И этому есть причина - каждый виджет, реализованный в рамках Flutter библиотеки, также заставляет реализовать необходимый функционал (функции для верстки, классы моделей, описание новых свойств атрибутов) в пакетах для бекенда: duit_go и duit_js. На первом этапе это представляло реальные трудности, добавление каждого виджета приводило к килотоннам нового кода. Сейчас же при разработке с такой проблемой встретиться можно достаточно редко, поскольку подавляющее большинство свойств Flutter уже перенесено в бекенд-адаптеры.
Отдельно стоит отметить развитие некоторых частей библиотеки виджетов Duit - это появление полноценных динамических списков (ListView.builder) и анимаций (через AnimatedBuilder и контроллеры).
Помимо добавления новых виджетов, было реализовано несколько крутых концепций, которые решали проблемы использования Duit и BDUI в частности: шаблонизация, использование пользовательских конфигураций виджетов, использование не поддерживаемых сетевых протоколов и тд. Прочитать статью-туториал об этих фичах можно тут.
Глобальные изменения коснулись библиотек для бекенда. Изначально я не уделил достаточное внимание дизайну и удобству решения, стараясь сделать все как можно быстрее, на что не раз напоролся при попытках использовать (хотя кому, как не автору знать, как пользоваться своим детищем). Требовалось привести библиотеки из состояния "и так сойдет" в состояние "пригодно к употреблению". Это привело к двум мажорным обновлением бекенд-адаптеров, которые, в основном, содержали изменения quality of life - улучшение семантики, более простое создание виджетов, передача дочерних представлений через параметры функции (конструкторы), а не через методы объекта (почему не сделал так сразу - тайна великая сие есть).
Обновления произошли и в сфере обеспечения качества Duit - я начал покрывать код тестами. Сперва я начал писать тесты, чтобы немного расслабиться. Они не требовали такого напряжения, как разработка новых фич, но при этом дарили некоторую уверенность в том, что я делаю полезное дело. Но такие упаднические настроения присутствовали у меня до первого пойманного с помощью тестов бага. Для меня стали очевидны преимущества тестирования, а в голове в это время выстроилась четкая картина того, как и что я должен тестировать для достижения максимальной надежности и устойчивости кодовой базы фреймворка.
За этим невзрачным демо-экраном невооруженным глазом очень трудно разглядеть целый ворох концепций и фич Duit, лежащих в его основе. На экране присутствуют компоненты (карточки), кастомные виджеты (svg), бесконечный список элементов с запросом дополнительных данных, обработка действий пользователя, обработка кастомных событий (навигация), задействовано большое количество свойств виджетов.
Если подводить некоторые итоги, то я могу с большой долей уверенности заявить, что в текущем состоянии Duit способен покрывать обширный список требований разработчиков. Я и моя команда готовим полноценное внедрение Duit в одно из наших приложений в ближайшем будущем (сейчас внедрение на этапе демонстрационного варианта для представителей менеджмента), а компания из Санкт-Петербурга, разрабатывающая ПО для морских судов, уже начала строить на базе фреймворка свой новый продукт. Дальше - больше!
CrossConf 2024
Один хороший человек, известный Flutter/Dart сообществу под ником MADTeacher и автор книги "Основы Dart", дал мне классный совет. Он предложил мне подумать над тем, чтобы попытаться популяризировать Duit, ведь то, что я делаю у себя "на заднем дворе" там и останется, если не заявить об этом миру.
Звезды сошлись летом, когда я узнал о call for papers на CrossConf, конференцию, которая тематически идеально соотносилась с тем, что я делаю. Так что вопроса о подаче заявки не стояло, я жаждал действия.
Выступление на CrossConf стало апогеем проделанной работы, еще одной преодоленной вершиной. Будучи совершенно неопытным спикером (это было мое первое публичное выступление), я легендарно волновался о том, чтобы, как минимум, не ударить в грязь лицом. В тот момент я презентовал не только Duit, но и себя лично. Так что груз ответственности явственно давил на плечи :)
Как я могу оценить свое выступление? Лишь фразой "хотелось бы и лучше". А мог бы лучше? Думаю, что нет. Только практика смогла мне показать тот огромный опыт и навыки, которым обладают крутые спикеры, те люди, которых приятно слушать, будто мёд в ушки льют. Поэтому я не имею морального права обесценивать их опыт, считая, что “васян с улицы” вроде меня может легко повторить их успех :)
Какие цели я преследовал, готовя доклад? Основной целью был рассказ о моем решении, привлечении к нему внимания сообщества. Но в ходе подготовки я пришел ко второй, неявной цели - рассказать участникам конференции о том, что подталкивает меня к тому, чтобы изо дня в день просыпаться посвящать время Duit. Эта часть была довольна эмоциональна, но разве мотивация и вдохновение могут строиться только лишь на сухих фактах, диаграммах и графиках?)
Идеи и цели
Я уверен - история только начинается, ведь прошел всего лишь один год, хоть он и показался до невозможности долгим. Duit для меня за время своего существования превратился из обычного пет-проекта, каких было множество, и испытательного полигона для "передовых" идей в дело, которым можно гордиться и не стыдно похвастаться.
Как вы могли понять, у меня с Duit все серьезно. И будучи настоящим мужчиной, мне требуется строить планы на совместное будущее :)
Но давать пустые обещания любимым - не наш путь, а значит я не стану коммититься в том, что не смогу выполнить. Поэтому предлагаю распилить этот раздел на описание идей и перечисление целей. Где идея - это большая и сложная, но при этом выполнимая задача, требующая значительного изучения теории и технологий, а также плохо поддающаяся оценке и прогнозированию. Цели в свою очередь - это разрешимые в короткие (относительно) сроки задачи: добавить новый виджет, пофиксить баг, внедрить небольшую фичу. И именно с определения целей на ближайший год я хотел бы начать:
Цель №1 - Документация
Документация Duit - это то, за что мне не стыдно. Нет документации - нет стыда. Первоочередной задачей на ближайший год является исправление этого досадного недоразумения. Краткий план на первую итерацию: описание базовых концепций фреймворка, описание продвинутых возможностей (компоненты, кастомные виджеты, протоколы, скрипты и тд), руководства по старту разработки. План на будущие итерации: cookbook с лучшими практиками, которые предстоит еще наработать, документация API виджетов и их corner-case.
Цель №2 - Управление проектами и сообщество
"Если хочешь идти быстро - иди один, если хочешь идти далеко - идите вдвоем." - африканская пословица. Истина, которая не всегда была для меня очевидна. Безусловно, хорошо, когда можно делать то, что считаешь нужным не считаясь с чьим бы то ни было мнением. Но, если я хочу чтобы Duit развивался, а я при этом не выгорел в адском пламени, то мне нужно апгрейдить свой скилл управления. Я считаю, что при грамотном управлении нагрузкой мне попросту станет легче жить, а при появлении контрибьюторов (на что я очень надеюсь) я не зашьюсь в микроконтроле.
Поэтому не менее важной подзадачей в достижении этой цели является создание понятного и прозрачного Contribution guide, который вкупе с документацией позволит снизить порог входа для новых разработчиков.
Цель №3 - Расширение библиотеки виджетов
На данный момент доступны 38 виджетов, в то время как в беклоге проекта лежат задачи на реализацию еще 30-ти. Итого 68. И здесь мы еще не посчитали slivers и другие специфичные виджеты (к ним я отношу implicit animated widgets).
И от более-менее понятных задач я хотел бы перейти к тем вещам, сделать которые очень хочется, но выполнение (и даже вероятность выполнения) прогнозировать крайне тяжело. Давайте посмотрим на них:
Идея №1- Редактор UI (конструктор)
На СrossConf в ходе моего доклада был задан отличный вопрос - "А можно как-то посмотреть, что ты верстаешь в процессе работы над Duit-экраном? Вот у DivKit есть playground, где верстка сразу же визуализируется".
Необходимость этого инструмента для меня была совершенно не понятна. Как и то, что не всякому Flutter-разработчику удобно создать интерфейсы на бекенде, на чуждом ему ЯП, хоть и с использованием знакомых семантических конструкций. Поэтому такой инструмент убил бы сразу двух зайцев и закрыл потребности большой массы потенциальных разработчиков.
Идея №2 - Джсоносжималка (компилятор)
Компактный формат передачи данных - логичный шаг в деле обеспечения максимальной производительности. Но поскольку для бинарных форматов я еще слишком мал и глуп, то хорошим вариантом для уменьшения размера итогового json (макета) служит преобразование обычного json в гораздо более компактный за счет использования более подходящих по размеру типов данных (например uint вместо строковых значений в enum).
Идея сама по себе не нова - я ориентируюсь на пример json-формата для библиотеки Lottie. Для этих целей мне понадобится разработать шустрый и компактный узкоспециализированный компилятор, да такой, чтобы его можно было через FFI максимально переиспользовать.
Идея №3 - App bundle
А что если я скажу, что можно сократить количество походов в сеть за макетами экранов, а также сократить объем пересылаемых по сети данных? Концепция App bundle заключается в том, что вместо многократных запросов макета для разных экранов, мы загружаем бандл, содержащий описание всех экранов приложения, граф навигации, мета-информацию. Эта функция может принципиально изменить подход при работе с Duit, а от этого она становится еще более интересной и перспективной.
Вместо заключения
Вот мне и удалось уложить в небольшой текст целый год кропотливого труда. Сейчас я оглядываюсь назад и думаю о том, что это был превосходный опыт. А глядя вперед, я ловлю себя на том, что я вдохновлен идеей дальнейшего развития фреймворка, создания вокруг него сообщества разработчиков.
Друзья, не требуется много усилий, чтобы оказать поддержку Duit. Для этого требуется лишь:
Поставить звездочку в репозитории проекта на Github, чтобы всегда быть в курсе обновлений.
Подписаться на мой телеграм-канал Boltology Tech, где помимо всего прочего я публикую интересную информацию из жизни проекта.
А если будете проездом в Калининграде, то велкам на встречи Mobile Assembly - сообщества мобильных разработчиков
Да пребудет с вами сила!