Все мы примерно представляем, как выглядит разработка в крупной компании и чем от неё может отличаться разработка в небольшой. А что происходит, если размеры компании стремительно меняются, и число сотрудников за пару лет увеличивается в десять раз? Когда стартап бурно растёт, и надо на ходу адаптироваться к новым обстоятельствам, как это сказывается на всём (от процессов до технологий)?
В нашей конференции HolyJS поучаствует компания ManyChat, у которой как раз так и происходит. Поэтому мы расспросили техлида разработки фронтенда Евгения Кувшинова и конкретно о ManyChat, и вообще о том, каково заниматься (фронтенд)-разработкой в стартапе.
— Для начала расскажите вкратце, чем вы занимаетесь в ManyChat, и чем занимается сама компания.
— Я пришёл в компанию как просто фронтенд-разработчик, за полгода подрос до лида фронтендовой команды. Тогда у нас ещё были такие функциональные команды — фронт, бэк, тестирование, продукт. А после того, как мы перестроили все наши процессы на LeSS, я вернулся обратно к разработке, и у меня практически не осталось прежних организационных задач. Занимаюсь user experience, стараюсь касаться продуктовой части, отчасти расти как product-менеджер, но при этом постоянно писать код.
Как компания мы помогаем бизнесу использовать относительно новый канал коммуникации — Facebook Messenger. ManyChat — это платформа для быстрого и простого создания чат-ботов для Messenger. Это не про искусственный интеллект, не про попытки эмулировать человеческое общение, а про сценарии, где такое и не требуется. С помощью наших ботов можно просто делать рассылки, а можно настроить более сложные интерактивные вещи вроде заказов, бронирования, программы лояльности. Они тоже делаются визуально и понятно, и этим может заниматься либо достаточно продвинутый владелец бизнеса, либо маркетолог без навыков программирования.
Можно посмотреть, как вообще работают боты в Messenger, на конкретном примере: как раз к HolyJS мы сделали специального бота.
— Наверняка вы постоянно слышите слова «Но ведь чат-боты ещё пару лет назад провалились». Ваш опыт показывает, что вообще-то в определённом контексте они вполне целесообразны?
— Да. Наверное, больше всего целесообразность доказывает даже не наш случай, а платформа WeChat. Это мессенджер, которым в Китае пользуются примерно все, в нём присутствует очень много бизнесов, и такие вещи, как заказ пиццы или такси, в Китае сейчас активно происходят через WeChat. И это показывает, что определённые интерактивные сценарии общения человека и бизнеса действительно хорошо работают, это удобно для обеих сторон.
А те юзкейсы, которые были хайповыми пару лет назад — вроде того, что ты можешь с ботом пообщаться как с человеком и он предложит лучший вариант рейса на самолёт — ну, это действительно не очень работает.
И мы реализовываем нечто близкое WeChat, но на других рынках: в первую очередь, в США, хотя и во всём мире тоже. У нас достаточно большое количество клиентов из Европы, да и в странах рядом с Китаем сейчас тоже многие пользуются Facebook Messenger.
— Переходя к теме роста: как давно появилась компания, и как росла с того момента до нашего времени?
— Компания появилась в 2015 году. Началось с того, что её сооснователю Микаэлу Яну нужно было сделать рассылку в Telegram (тогда там ещё не было каналов). Он понял, что это достаточно сложно, и пригодился бы специальный инструмент. В итоге Микаэл и Антон Горин сначала сделали платформу для создания ботов в Telegram. Платформа стала достаточно быстро расти, они попали в акселератор стартапов в Долине.
А пока были в акселераторе, Facebook открыл API для Messenger. И это был тот момент, когда они решили сделать резкий пивот, делать новый продукт именно для Facebook Messenger. Месячная аудитория Messenger — 1.4 миллиарда человек, а в Facebook множество компаний имеют свои представительства в виде официальных страниц. И для этих страниц можно создавать ботов.
Изначально сотрудников было трое: Микаэл, Антон и ещё один разработчик, который делал самую первую версию фронтенда. Осенью того же года были получены первые инвестиции и стало ясно, что можно начинать расширять команду. Тогда в компанию пришёл я и ещё трое разработчиков, так что в конце 2016 года нас было семеро. А сейчас, два года спустя, нас уже больше пятидесяти, и рост продолжается.
Если смотреть на числа самой платформы, то у нас уже больше 400 000 подключённых ботов. И мы хорошо растём по финансовым показателям: уже на текущий момент являемся прибыльной компанией, при этом продолжаем искать инвестиции, чтобы расти ещё активнее. В следующем году по количеству людей планируем как минимум удвоиться.
— Стартапы — очень экспериментальная область, где многое делается методом проб и ошибок (вроде упомянутого пивота, когда начали с одной концепцией, а потом на ходу поменяли). Как это сказывается на разработке? Значит ли это, что всегда надо быть готовым к ситуации «реализованная тобой фича окажется выброшена»?
— Действительно, есть такое, что можешь сделать какую-то фичу, а в итоге она не окажется востребована пользователями, у неё будет низкий adoption. Или она может вообще не добраться до продакшна, потому что мы сами, посмотрев на получившееся, поймём, что нам это не нравится.
Чтобы минимизировать количество таких ситуаций, самое первое, о чём мы думаем (ещё даже не при разработке, а при начале продуктовой проработки фичи) — это мотивация. Зачем мы её делаем, для кого, насколько сильно она повлияет на уже существующих пользователей, насколько нам самим это нравится (будем ли мы радоваться и гордиться тем, что в нашем продукте появилась такая штука). Определившись с мотивацией, возможно, проведя опросы в нашем пользовательском комьюнити или ещё какие-то интервью с нашими пользователями, мы приступаем к разработке. Дальше мы готовим фичу к спринту, такой процесс называется PBR (Product Backlog Refinement): сначала она попадает в бэклог, потом поднимается там по рейтингу, и в какой-то момент она, уже хорошо описанная, может попасть в спринт.
Непосредственно в спринте первое, что мы делаем — это, если не понимаем, как она будет выглядеть, делаем какие-то макеты и прототипы. Но, как бы странно это ни звучало, иногда это делается уже вместе с разработкой. Потому что иногда очень сложно понять, как пользователь будет себя чувствовать с интерфейсом, просто сделав какие-то макеты и нарисовав иллюстрации.
Довольно часто на фронтенде мы делаем прототипы или интерактивные фичи, которые в принципе уже работают, их можно прокликать и прочувствовать. И потом в тесной работе с дизайнерами мы доводим эти прототипы до варианта, который пойдёт в продакшн. Но, тем не менее, при создании вот этих прототипов тоже нередкое явление, когда ты делаешь его, смотришь, и сам понимаешь «нет, это не зайдёт, это неудобно». Мы стараемся пользоваться своим же продуктом, делать ботов, чтобы ещё раньше наших пользователей узнавать, где могут возникнуть какие-то проблемы. Ну и в целом делаем акцент на user experience, пытаемся построить самую простую в использовании платформу.
— При бурном росте компании наверняка сталкиваешься с тем, что процессы, которые работали для нескольких человек, перестают работать при переходе к десяткам людей. Как у вас менялась разработка с организационной точки зрения?
— Это было сложно. В начале года у нас была достаточно тяжёлая ситуация, когда несколько фич мы делали уже по несколько месяцев, они были постоянно в состоянии «ещё чуть-чуть доделать и выкатим в продакшн», но это «ещё чуть-чуть» никак не наступало.
Когда мы только начинали, нас было семь человек. У нас был scrum, были спринты, всё строилось и происходило достаточно хорошо. Когда мы подросли до 20-30 человек, у нас, как и во многих компаниях, появились функциональные команды: бэкенд, фронтенд. Со своими процессами, со своими спринтами внутри, со своими очередями задач. И мы не делали задач, которые называются конкретно «вот такая-то фича, которая такому-то пользователю принесёт такую-то пользу». Задачи каждой команды назывались в духе «фронтенд: переверстать вот такой так кусочек интерфейса, добавить какую-то кнопку».
И это было плохо по многим причинам. Во-первых, когда у нас много разных очередей и кусочки одной и той же бизнесовой задачи стоят в них с разным приоритетом, становится практически невозможно понять, когда же задача полностью будет готова. А конкретному разработчику становится сложнее понять, что он делает. Потому что он делает какой-то кусочек, описанный для него, а как пользователи будут потом радоваться результату, он не знает, потому что может даже во многом не знать, зачем это всё нужно.
В какой-то момент мы поняли, что так дальше нельзя. Да, можно понемногу тюнить, итерировать, продолжать проводить спринты и ежедневные стенд-апы (которые начали занимать уже больше, чем по полчаса, потому что на них присутствовала вся команда, но которые уже не давали ничего). Но это косметические меры, не решающие главную проблему.
И в тот момент один из ребят в компании донёс до нас информацию о том, что есть такая штука, которая называется LeSS или Large-Scale Scrum: скрам именно для уже больших и растущих команд. Посидев несколько вечеров в переговорках, пообсуждав вообще всё, что у нас происходит, CEO и CTO (Мика и Антон) приняли очень тяжёлое бизнесовое решение: весь процесс разработки (как мы проектируем фичи, реализуем и выкатываем) мы целиком выкинем в мусорку. Закончим идущий сейчас спринт, а дальше выстроим всё заново.
Решение было сложное, и поняв, что мы это делаем, мы ещё достаточно долго думали: «Блин, а получится или нет?» Но решили всё-таки попробовать, обратившись к книге по LeSS и к сертифицированным тренерам. Запустились по-новому, сделали кроссфункциональные команды — на старте их было три. Запустили короткие недельные спринты по правилам LeSS (правила в том смысле, какой набор встреч должен быть на этих спринтах). Не буду рассказывать все детали, но за первый недельный спринт из висящих на нас, кажется, восьми задач, которые мы не могли выкатить уже несколько месяцев, мы выкатили в продакшн, если не все, то большую часть. И мы просто не понимали, что происходит. Как так? Почему мы не могли этого сделать раньше? И почему это получилось? Это было очень круто и мы стали двигаться дальше, брать новые задачки, решать их в кроссфункциональных командах гораздо быстрее.
Конечно, были какие-то сложности и непонимания тоже. Но в целом, наверное, большей части команды складывающийся процесс очень нравится, потому что time to market у нас для фич значительно сократился, можно очень быстро всё делать, выкатываться в продакшн. А помимо этого мы стараемся доносить обратную связь от наших пользователей, чтобы разработчики видели, насколько людям нравится то, что они делают.
Ещё интересным моментом стало то, как мы выкатываем фронтенд после того, как мы перешли на LeSS. Мы поняли, что сейчас разделимся на отдельные кроссфункциональные команды, и первое время (как минимум до того, как фронтенд-комьюнити заработает), будем общаться значительно меньше. И мы научились выкатывать фронтенд в любое время «по щелчку пальцев», когда нам это нужно… У нас была одна-единственная встреча перед стартом нового спринта, где мы сказали, что у нас есть наша основная ветка, и её можно выкатить в любой момент. До этого у меня были мысли, что мы должны обязательно построить систему интеграционных UI-тестов, которая будет проверять каждую сборку, что там должен быть огромный процент покрытия, и только если она «зелёненькая», мы можем покатиться. Но это была какая-то несбыточная мечта, потому что продукт очень быстро растёт, а в этом случае как ни старайся, огромный процент покрытия всё равно не успеешь держать. В итоге, договорившись со всеми разработчиками и дав им эту ответственность, нам удалось сделать так, что теперь код из нашей основной ветки действительно всегда работает и мы всегда можем просто взять и выкатить оттуда любую сборку, которая нам нужна.
— Ух, спасибо за подробный ответ. Хочется предположить, что, помимо описанного перехода, должен был произойти ещё и переход от «фуллстековости» к узкой специализации: когда всё в проекте делают лишь несколько человек, волей-неволей приходится заниматься самыми разными вещами, а когда больше пятидесяти, у каждого чёткий круг задач. Это так?
— Когда нас было мало, действительно приходилось решать много задач из разных областей. Например, я какое-то время немного и занимался системным администрированием, и настраивал CI-систему. А сейчас, с переходом к LeSS, этого гораздо меньше.
Но это не значит, что теперь все замкнулись в узких ролях. Когда ты приходишь в компанию, у тебя есть основная компетенция (будь то хоть бэкендер, хоть дизайнер), и никто не будет мешать тебе прокачивать именно эту вертикаль в космос, но в то же время LeSS даёт возможность (именно возможность) развиваться в смежных направлениях.
Мы разделены на небольшие стандартные scrum-команды, в которых шесть (плюс-минус три) человек, которые собраны вместе и сидят рядом за смежными столами. А значит, фронтендер всегда может пообщаться и с бэкендером, и с дизайнером. Помимо того, что таким образом выстраивается классная коммуникация, ты ещё и можешь учиться у этих ребят. И мы приветствуем, если человек, который занимается фронтом, например, на этот спринт хочет взять себе какую-то небольшую бэкендовую задачку и прокачать эту область. Потому что, чем больше у тебя знаний из разных областей, тем больше у тебя фокус на весь продукт целиком, а тогда у тебя лучше получается решать и свои задачи. Когда ты начинаешь понимать, почему дизайнеры так делают, почему продуктологи так делают, ты иногда можешь уже сам начать строить интерфейс, который потом просто покажешь им, и они скажут «да, классно». И, соответственно, ты можешь свою работу делать быстрее.
— Стартапы находятся «на острие прогресса». Означает ли это, что и при выборе технологий вы легко можете затащить в продакшн что-то совсем новое? И есть ли какие-то меры предосторожности, чтобы это не превратилось в погоню за «блестящими новыми штуками», способную навредить компании?
— Короткий ответ: да, суперновое, классное и интересное можно, мы это всячески приветствуем. Но, конечно, есть определённые критерии по внедрению новых технологий.
Если находишь какую-то технологию, которая тебе интересна, дальше надо принести её в комьюнити. Хотя у нас в компании больше нет фронтендовой команды, есть фронтенд-комьюнити, в котором мы периодически собираемся и как раз обсуждаем подобные вопросы. Там можно рассказать всем, почему это здорово и почему нам в будущем с этим будет легче жить. У некоторых компаний, наверное, бывает какая-то конкретная система отбора, сложная таблица со сравнениями, которую нужно заполнить. У нас ничего такого нет, все решения принимаются на уровне каких-то очень субъективных ощущений, но при этом действительно хорошие и интересные технологии у нас появляются достаточно быстро.
Иногда появляются и те вещи, которые ещё не дошли до релиза. Мы начали использовать библиотечку для создания панелей в React, когда она была ещё достаточно сырой, и, насколько я помню, даже немножко туда доконтрибьютили. Мы начали использовать Babel 7 с какой-то бета-версии, потому что он позволил нам собирать проект чуть-чуть быстрее, чем предыдущий.
И, наверное, никто в команде ни разу не жаловался, что он хотел какую-то новую классную штуку, а ему сказали: «Нет, у нас вот такая политика, мы не будем этого делать». И при этом я не могу припомнить ни одной проблемы, которую вызвал бы такой подход, приветствующий новые интересные технологии. Очень странно для меня, потому что, по моему предыдущему опыту, я принимал много неправильных решений как раз на этом уровне. Но в ManyChat, может быть, как раз с помощью комьюнити, может быть, ещё по каким-то причинам, у нас нет таких вот фейлов, когда мы что-то выбрали, а потом пришлось взять и переписать половину кодовой базы на другую технологию, потому что эта не зашла.
— Ещё про «острие прогресса»: хочется предположить, что стартап позволяет спокойно вздохнуть «не придётся сталкиваться с легаси-кодом». Это так?
— Ну, слово «legacy» каждый понимает по-своему. Если понимать под ним, например, код старше трёх лет, то в компании младше трёх лет, конечно, его нет. Но можно это понятие ужесточать, тогда и у нас найдётся какой-то процент легаси-кода. С той точки зрения, что пусть он написан и не три года назад, а всего лишь несколько месяцев назад, но тогда мы не знали, как делать что-то правильно, а сейчас научились, мы можем сто строк вместо тысячи, и они будут делать то же самое ещё более надёжно. Такой код, конечно, есть, это неизбежно. Но нет ничего такого, для чего нам приходилось бы искать каких-то «бородатых разработчиков», потому что только они знают этот язык программирования, а мы не можем от него отказаться.
— Насколько разработка в стартапе способствует «велосипедостроению»? Пока компании-гиганты делают внутри всё подряд, вам не до того? Или стартап как раз такое место, где всё делают по-своему?
— Для нас на первом месте business value. Мы уже прибыльны, но если мы замедлимся и начнём проигрывать кому-то, это будет очень больно. Поэтому, если сторонняя разработка согласуется с бизнес-требованиями, решает задачи бизнеса, и у неё нет каких-то больших проблем, то мы её смело берём и используем. А если при использовании всё-таки возникает какое-то недовольство, ставим себе в техдолг задачку, что мы хотим это сделать сами круче и лучше. Но самое главное — это всё-таки изначально закрыть задачу и дать нашим клиентам требуемые фичи.
— А как активный рост сказывается на технологиях, используемых в разработке? Часто ли оказывается так, что что-то «перерастаете»?
— Ну, бурный рост — это больше про бэкенд. Наши сотрудники, которые занимаются бэкендом, каждый месяц сталкиваются с практически удваивающейся нагрузкой, им приходится всё масштабировать, где-то добавлять железа, что-то ускорять. А у нас на фронтенде всё гораздо проще: новых пользователей становится больше, но каждый из них приходит со своим железом и запускает наше приложение у себя в браузере.
Но изменения есть. Первая версия ManyChat была сразу на React, но для хранения состояния у нас использовалась библиотечка Baobab. Это такая реализация иммутабельного дерева, и всё это связывалось с React через кастомную обвязку с экшенами. Из слоёв абстракции там был собственно view с React, кастомные экшены и store с Baobab. Было это не очень удобно, много чего не хватало, и в принципе погружаться в это тоже было достаточно тяжело.
Поэтому в 2017 году мы решили взять известные нам и широко распространённые во фронтенде технологии. Мы оставили React, добавили Redux с небольшим набором middleware для него – взяли Thunk и написали несколько своих для работы с бэкендом через Fetch API. К слоям абстракции добавились редьюсеры и селекторы, и с этим ядром мы живём уже два года. В принципе, нас всё полностью устраивает, а приложение растёт по функциональности, но остаётся хорошим, отзывчивым.
— Поскольку стартапы решают проблемы, которые до них не решали, то и технологические задачи в них могут оказываться не теми, с которыми все сталкиваются каждый день. Было ли у вас что-то, отличающееся от «обычного» фронтенда?
— У наc есть инструмент для визуального программирования схем взаимодействия между подписчиком и ботом, мы называем эти схемы Flow, а сам инструмент — Flow Builder. Вот тут можно увидеть, как это выглядит:
Оказалось, для создания отзывчивого и плавного интерфейса карты с зумом, панорамированием и большим количеством объектов не обойтись без 2D-графики. В итоге наш Flow Builder технически работает на PixiJS — универсальном рендерере для WebGL/Canvas.
В России эта технология знакома в основном разработчикам из геймдева. Но поскольку мы не геймдев, у нас своя специфика. В играх PixiJS каждый раз после рендеринга дёргает requestAnimationFrame и постоянно рисует. Если у нас сделать так же, то пользователь оставит ноутбук с открытой вкладкой на полчаса, а вернувшись, обнаружит, что ноутбук разрядился. Причём ещё и ноутбук у пользователя может быть совсем не геймерским (у меня тогда был 12-дюймовый MacBook, который не может похвастаться производительностью, я как раз на нём и тестировал). В общем, мне приходилось искать разные решения для того, чтобы на нём всё было плавно и быстро, при этом не разряжая ноутбук.
В итоге мы для всех элементов геометрии и всего, что используем, сделали свои прокси-обёртки, которые регистрируют какие-то изменения, плюс сделали свои обёртки-обработчики на различные браузерные события, и сделали так, что у нас отрисовка происходит только тогда, когда это нужно. Так получилось сделать собственно достаточно быстрый и удобный инструмент для 2D-рисования.
— И насколько такие задачи усложняют жизнь по сравнению с «типичными»? Например, приходилось ли в этой ситуации сталкиваться с тем, что на возникающие вопросы гугл не даёт ответов?
— Ну, хотелось бы, конечно, сказать, что всё было ужасно сложно, и до нас этого никто не делал… Да, большинство сервисов остаются в рамках родного HTML, а когда приходится уходить в Canvas и WebGL для отрисовки значительной части интерфейса, появляются сложности. Но выбрав Pixi, мы сделали достаточно хороший выбор.
Мы тогда изучили большое количество технологий: проверили множество библиотек, которые просто рисуют на Canvas, брали ещё какие-то рендереры под WebGL. Но Pixi для нас оказался самым быстрым и удобным, а самое главное, что вокруг него есть достаточно большое комьюнити. Ребята активно охотно отвечают на вопросы, помогают фиксить баги или находить какие-то обходные пути. Контрибьютить нам даже не пришлось, а на несколько issue, которые мы открывали у них на GitHub, они очень быстро отвечали, рассказывали, что и как делать.
Проблемы, тем не менее, возникают, потому что на Canvas остаёшься без всего, что дают HTML и CSS. Всю разметку и вёрстку приходится писать самому вручную в координатах, нет никакого Flexbox и никакого блочного layout’а, и вёрстка занимает достаточно много времени. Нет никакой работы с текстом и с пользовательским вводом. У нас в ближайшее время появятся поля ввода прямо на Canvas, это делается через хак: когда ты нажимаешь на этот текст на Canvas, поверх него отрисовывается textarea, она масштабируется через CSS scale и эмулирует примерно то же положение и тот же размер текста, и для пользователя остаётся незаметно: он как бы в Canvas что-то пишет, а на самом деле у него там сверху отрисовывается слой в HTML.
Ещё из интересного было то, что пришлось вспоминать математику. Например, Pixi даёт возможность рисовать какие-то линии, кривые Безье, у нас объекты на Flow Chart соединяются такими плавными линиями. Но они посчитали не очень-то нужным сделать эти линии сколько-нибудь интерактивными, чтобы для них работали стандартные события: наведение мышки, клики и так далее. И чтобы посчитать область, которую занимает линия, нам пришлось вспоминать математику, тригонометрию и учиться рисовать полигоны вокруг кривых Безье, чтобы создать эти интерактивные области. Было весело.
— Вопрос напоследок. Вероятно, среди читателей интервью есть разработчики, которые не понимают, насколько им подошла бы работа в стартапе. По интервью они уже могли сделать какие-то выводы, но хочется ли сказать им что-то ещё?
— Наверное, стартап хорош для тех, кто готов постоянно учиться. Если хочется спокойную работу, когда ты научился делать что-то одно и готов на протяжении многих лет повторять это с небольшими изменениями, это не про нас. Тут всегда придётся развиваться, учить что-то новое, применять новые технологии.
И ещё: это прозвучит какой-то фразой-клише, но если есть желание что-то изменить в мире и чего-то добиться, то это как раз к стартапам, тем местам, где создаются новые продукты или технологии. Мне лично такое положение вещей, которое сложилось у нас, очень по душе. Но при этом у меня есть огромное уважение и понимание по отношению к людям, которые строят и поддерживают уже существующие продукты, какие-то большие объёмные энтерпрайз-решения. Это тоже здорово, это огромная работа, которая тоже влияет на большое количество пользователей и каждый день делает их жизнь проще, лучше, удобнее. Но всё-таки, если хочется развития, если хочется достижений, то я думаю, это про стартап.
Автор: phillennium