Project Manager Skills:
свои макеты от заказчика
свои макеты от заказчика
Упражняемся в управленческих поединках и детально разбираем непростой кейс
Управленческие поединки понедельничным утром — эдакая morning routine для наших менеджеров. О пользе поединков для прокачки скиллов мы говорили не раз, а сегодня на их примере предлагаем разобрать кейс, к которому не так-то просто подступиться даже опытному менеджеру. Много тонкостей и технических нюансов, в которых запросто можно утонуть (и запороть всю коммуникацию с клиентом). Надевайте водолазный костюм — мы начинаем :)
Ситуация
Винный интернет-магазин решил сделать редизайн. Первоначально менеджер интернет-магазина искал студии и давал тестовое задание нарисовать карточку товара. Так как перспективы работы над проектом были на несколько миллионов рублей, менеджер настаивал на бесплатном выполнении тестовых заданий.
Одна из студий заартачилась, соглашаясь рисовать макеты только по своему обычному процессу: сначала аналитика, потом прототипирование и только затем макет, причем, по своему обычному прайсу. Клиент решил с ними не работать, однако всеми бесплатными работами в итоге остался недоволен и нарисовал макеты, которые его почти устраивали, самостоятельно.
Запомнив артачущуюся студию, клиент обратился к ним с запросом на доведение макетов до ума. Сроки по разработке горят. Бэкэнд заказчик планирует делать самостоятельно, на фронтэнде хотел бы использовать реактивный фреймворк (фреймворк, благодаря которому состояние интерфейса автоматически будет автоматически реагировать на изменение данных на странице — например, Vue. js или React. js), но не знает, как и в какой последовательности решать задачу. UI-kit отсутствует, отрисовано на данный момент несколько страниц.
Клиент хотел бы:
Роли и интересы
Клиент: получить понятный план работ, убедиться в компетентности студии.
Менеджер студии: продать проект в выгодной для себя конфигурации.
Одна из студий заартачилась, соглашаясь рисовать макеты только по своему обычному процессу: сначала аналитика, потом прототипирование и только затем макет, причем, по своему обычному прайсу. Клиент решил с ними не работать, однако всеми бесплатными работами в итоге остался недоволен и нарисовал макеты, которые его почти устраивали, самостоятельно.
Запомнив артачущуюся студию, клиент обратился к ним с запросом на доведение макетов до ума. Сроки по разработке горят. Бэкэнд заказчик планирует делать самостоятельно, на фронтэнде хотел бы использовать реактивный фреймворк (фреймворк, благодаря которому состояние интерфейса автоматически будет автоматически реагировать на изменение данных на странице — например, Vue. js или React. js), но не знает, как и в какой последовательности решать задачу. UI-kit отсутствует, отрисовано на данный момент несколько страниц.
Клиент хотел бы:
- выбрать лучший вариант из своих макетов и доработать силами студии дизайн;
- согласовать концепт, привести все макеты к единому виду и собрать в компоненты;
- улучшить мобильную версию сайта (где карточка товара сейчас выглядит особенно грязно);
- понять процедуру совместной работы над проектом, бэкэндом и фронтендом, кто, как, и что будет делать.
Роли и интересы
Клиент: получить понятный план работ, убедиться в компетентности студии.
Менеджер студии: продать проект в выгодной для себя конфигурации.
Что произошло?
В первом диалоге менеджер студии множество вопросов пытается отложить «на потом». Это очень сильно выдаёт его неосведомленность в технических вопросах: как будет построена работа, как связать фронтенд и бэкенд и так далее. В итоге, по факту, переговоры ведет клиент, задает вопросы клиент, и предложения вносит тоже клиент — поэтому он легко мог бы под этим соусом пропихнуть какие-то свои идеи и хотелки.
Рецепт
Если у вас недостаточно компетенций, чтобы ответить на какой-то вопрос клиента, не стесняйтесь взять время, уточнить и связаться с ним снова. Это выглядит куда профессиональнее, чем попытки выкрутиться и рассказать о чём-то в общих словах.
Во втором диалоге менеджер чётко раскладывает действия по шагам и рассказывает, как всё-таки будет связан фронтенд с бэкендом. Напомним, что бэкенд — всё то, что на сервере, а фронтенд — всё, что на клиенте (в браузере). В нашем кейсе клиент хочет оставить бэкенд себе, а фронтенд отдать студии. Это значит, что где-то нужно будет «встретиться».
Разбор кейса
Фронтенд на реактивном фреймворке
Клиент хотел использовать на фронтенде реактивные фреймворки. Мы на проектах обычно юзаем React.JS и Vue.JS, принципиальной разницы между ними нет — оба решают одну и ту же задачу. Vue попроще, React болтливее (академично).
На сайтах с нереактивным фреймворком бэкенд генерирует HTML-страницы (шаблоны), а на фронтенде браузер с их помощью отрисовывает уже готовый экран. Это классика, ей сто лет, она простая и надежная. На каждое изменение пользователя (например, клик) нужно получать от сервера новый шаблон страницы или делать ajax-запрос. Это долго.
На сайтах с реактивными фреймворками отрисовка всех шаблонов идет на стороне фронтенда с помощью JavaScript. Многие операции (например, работу корзины) можно вообще организовать без обращений к серверу, реагируя на действия пользователя «реактивно». Там, где обращения к серверу нужны — можно сделать легковесный API и обмениваться компактно только нужной информацией, а не целыми страницами. (подробнее о том, как работают реактивные фреймворки рассказываем здесь и здесь).
На сайтах с нереактивным фреймворком бэкенд генерирует HTML-страницы (шаблоны), а на фронтенде браузер с их помощью отрисовывает уже готовый экран. Это классика, ей сто лет, она простая и надежная. На каждое изменение пользователя (например, клик) нужно получать от сервера новый шаблон страницы или делать ajax-запрос. Это долго.
На сайтах с реактивными фреймворками отрисовка всех шаблонов идет на стороне фронтенда с помощью JavaScript. Многие операции (например, работу корзины) можно вообще организовать без обращений к серверу, реагируя на действия пользователя «реактивно». Там, где обращения к серверу нужны — можно сделать легковесный API и обмениваться компактно только нужной информацией, а не целыми страницами. (подробнее о том, как работают реактивные фреймворки рассказываем здесь и здесь).
Преимущества реактивных фреймворков
Когда идёт работа с HTML-страницами, сервер каждую страницу генерирует целиком и передает ее в бразуер пользователя (на клиента) — это довольно большой объем кода. Когда идёт работа с реактивными фреймворками, можно сделать так, чтобы при клике на ссылку передавалась не вся страница целиком, а только данные, необходимые для отрисовки конкретных кусочков. Перезагрузки страницы, как таковой, не происходит — вместо этого подгружается небольшое количество данных, и это выглядит гораздо быстрее (данные на странице интерактивно меняются в зависимости от действий пользователя).
По скорости это значительно быстрее, а вот по сложности программирования есть ряд нюансов. Смотрите сами, как шустро работает фильтр и переход в карточки каталога на нашем проекте «Заработал».
По скорости это значительно быстрее, а вот по сложности программирования есть ряд нюансов. Смотрите сами, как шустро работает фильтр и переход в карточки каталога на нашем проекте «Заработал».
В нашей истории клиент хочет делать бэкенд самостоятельно. Объём работ студии сводится к вёрстке макетов и адаптива, получению данных и описанию какой-то бизнес-логики.
Вопрос: как связать в таком случае бэкенд с фронтендом? Через API, конечно. По типу протоколов API есть несколько подходов:
REST API (REST JSON)
Это подход, когда API реализовано так, что оно не помнит предыдущее состояние. То есть каждый REST-запрос клиента к серверу содержит в себе достаточную информацию о желаемом ответе сервера, и сервер не хранит информацию о клиентской сессии. Если ещё проще — есть конкретные адреса, по которым вы стучитесь к серверу, задаете конкретный запрос, и вам на них отдают конкретный ответ.
XML / SOAP на основе XML
Когда-то это был распространённый способ, но сейчас он отходит в прошлое, как и многие майкрософтовские технологии-мастадонты. Минус такого подхода, по сравнению с JSON, — он очень «болтливый», данные в JSON получаются гораздо компактнее.
GRPC
Новый формат, который мы использовали на проекте SingularityApp. Предыдущие два вида API легко читаются в текстовых редакторах: можно посмотреть на них глазами и понять, что и куда передается. Формат GRPC — бинарный: он передаёт нули и единицы :)
Его преимущества:
1) данные передаются ещё компактнее;
2) формат умеет делать типизацию.
Например, вы хотите передать в Rest API стоимость товара — по идее, это должно быть число. Но никто не запрещает на уровне JSON добавить туда текстовое написание числа (и потом смотреть, как это всё «навернется»). GRPC более «злой» в этом плане — он заставляет типизировать данные, и если попытаться передать что-то не то, он просто не даст этого сделать. С ним есть некоторые технические сложности при работе с браузерами (но это решаемо и это уже совсем другая история).
Вопрос: как связать в таком случае бэкенд с фронтендом? Через API, конечно. По типу протоколов API есть несколько подходов:
REST API (REST JSON)
Это подход, когда API реализовано так, что оно не помнит предыдущее состояние. То есть каждый REST-запрос клиента к серверу содержит в себе достаточную информацию о желаемом ответе сервера, и сервер не хранит информацию о клиентской сессии. Если ещё проще — есть конкретные адреса, по которым вы стучитесь к серверу, задаете конкретный запрос, и вам на них отдают конкретный ответ.
XML / SOAP на основе XML
Когда-то это был распространённый способ, но сейчас он отходит в прошлое, как и многие майкрософтовские технологии-мастадонты. Минус такого подхода, по сравнению с JSON, — он очень «болтливый», данные в JSON получаются гораздо компактнее.
GRPC
Новый формат, который мы использовали на проекте SingularityApp. Предыдущие два вида API легко читаются в текстовых редакторах: можно посмотреть на них глазами и понять, что и куда передается. Формат GRPC — бинарный: он передаёт нули и единицы :)
Его преимущества:
1) данные передаются ещё компактнее;
2) формат умеет делать типизацию.
Например, вы хотите передать в Rest API стоимость товара — по идее, это должно быть число. Но никто не запрещает на уровне JSON добавить туда текстовое написание числа (и потом смотреть, как это всё «навернется»). GRPC более «злой» в этом плане — он заставляет типизировать данные, и если попытаться передать что-то не то, он просто не даст этого сделать. С ним есть некоторые технические сложности при работе с браузерами (но это решаемо и это уже совсем другая история).
Декомпозиция задачи клиента
Как выглядит задача клиента из кейса? Он хочет сделать бэкенд сам, у него есть какие-то макеты, которые хотелось бы перевести в HTML-формат и привязать к ним реактивный фреймворк. Плюс нужен какой-то API — какой, пока непонятно. И вдобавок он хотел бы макеты переработать/доработать силами студии.
Чтобы разложить такую огромную задачу по полочкам, хорошо использовать формат майндмэпов — описать, кто, куда и зачем «стучится» (например, в XMind).
Чтобы разложить такую огромную задачу по полочкам, хорошо использовать формат майндмэпов — описать, кто, куда и зачем «стучится» (например, в XMind).
Как выглядит майндмэп в XMind
Такой документ хорош, когда нужно составить спецификацию, как должна работать связка фронтенда и бэкенда. Такой документ может служить предварительным ТЗ, по которому уже можно будет составлять реальный протокол.
Но даже такой майндмэп сложно составить, поскольку совершенно неизвестно, что там внутри макетов от клиента. Логично, что у менеджера сразу возникает вопрос «Откуда эта хрень на странице?!». В такой ситуации используйте наш фирменный метод Светофора: распечатайте макеты, возьмите аналитика и маркером покрасьте блок за блоком, слово за словом, что и откуда на странице берётся. Красным — где вообще непонятно, жёлтым — где есть сомнения, зелёным — где во всём уверены. И вот уже на основе этого можно строить подобный майндмэп.
Но даже такой майндмэп сложно составить, поскольку совершенно неизвестно, что там внутри макетов от клиента. Логично, что у менеджера сразу возникает вопрос «Откуда эта хрень на странице?!». В такой ситуации используйте наш фирменный метод Светофора: распечатайте макеты, возьмите аналитика и маркером покрасьте блок за блоком, слово за словом, что и откуда на странице берётся. Красным — где вообще непонятно, жёлтым — где есть сомнения, зелёным — где во всём уверены. И вот уже на основе этого можно строить подобный майндмэп.
Что такое Swagger
API нуждается в документации. А также в возможности поработать с ним и посмотреть, что отдает каждый метод на самом деле. Обе задачи решает Swagger — классная штука, созданная как раз для работы и документирования RESTful API.
Swagger гораздо лучше спецификации в формате .doc, потому что это «живая» документация — можно сразу потыкать и проверить, как работает какой-то параметр. Через него можно вызывать серверные методы API и смотреть, что они отдают.
Mock-данные для API
Это понятие пришло к нам из мира автотестов. Однако его можно и нужно использовать при быстрой разработке интегрированных систем. Как в нашем случае.
Например, у вас есть каталог товаров, и у API есть метод products-catalog, который возвращает перечень товаров для какой-то конкретной категории. Пока заказчик начнет делать эту реализацию на бэкенде (запросы к базе, вывод того-сего) — пройдет много времени. И чтобы не ждать, мы можем положить на сервер специальные файлы, которые будут имитировать работу API. Собственно, объекты, которые имитируют реальные данные на сервере, в тестировании (в том числе в автотестах) называются mock-объектами.
Например, у вас есть каталог товаров, и у API есть метод products-catalog, который возвращает перечень товаров для какой-то конкретной категории. Пока заказчик начнет делать эту реализацию на бэкенде (запросы к базе, вывод того-сего) — пройдет много времени. И чтобы не ждать, мы можем положить на сервер специальные файлы, которые будут имитировать работу API. Собственно, объекты, которые имитируют реальные данные на сервере, в тестировании (в том числе в автотестах) называются mock-объектами.
Когда вы делаете шаблон майндмэпа и готовите описание того, что должно быть в API, у вас уже здесь появляются конкретные примеры (например, файл со списком товаров) — это как раз то, что может быть на стороне сервера. Эти примеры можно брать за mock-объекты, не дожидаясь реализации бэкенда от заказчика.
Последовательность работы с mock-объектами
Когда backend-разработчик начинает добавлять свои методы для API, мы их постепенно подключаем к сайту. Естественно, в какой-то момент всё это начнет падать, глючить, не работать, и начнутся вопросы, на чьей стороне это случилось. Скорее всего, что-то будет неправильно реализовано на стороне сервера, или не будет учтен какой-то редкий, специфический случай. Тут важно настроиться на нормальную коммуникацию, и за пару-тройку дней выполнить все пуско-наладочные процедуры. Увы, это неизбежно. Главное не говниться.
Кто за что отвечает
Вообще, нам больше нравится делать все под ключ. Но если очень хочется — раздробить задачу можно. Будет больше коммуникаций и выше издержки на переговоры, но все решаемо.
Реактивные фреймворки VS поисковые системы
Для поисковых систем нужно, чтобы данные отдавались в HTML-формате, иначе никаких данных на страницах они не увидят (и пока, ранжирование!). Из-за этого на сайтах, которые должны индексироваться (а индексируются не все — личные кабинеты или дашборды — нет), приходится использовать архитектуру SSR (Server Side Rendering).
Например, у вас есть JavaScript, который получает на вход, скажем, JSON, а на выходе отдает HTML-страницу. Но это работает в браузере, а нам нужно, чтобы поисковая система получала HTML-файл.
Среди возможных посетителей сайта есть поисковые роботы и есть реальные люди. Когда на сайт приходит реальный пользователь, он получает шаблон с отрисованными JS и HTML. Когда работает поисковый робот, для него мы делаем прослойку, чтобы весь HTML отработал на сервере (используя, например, фреймворк Nuxt. JS). А чтобы так произошло, на сервере нужно поставить тот же JS-движок, который используется во всех современных браузерах, — Node. JS (выдернут из браузера Chrome и вставлен в серверную среду).
Нюанс со сторонними скриптами
Когда заказчик получает на руки сайт, то, в первую очередь, стремится добавить метрики и прочие штуки вроде Google TagManager, JivoSite, MindBox, Retail Rocket. Скорость работы реактивных фреймворков обеспечивается за счёт того, что при изменении страницы они не работают с HTML напрямую. Вместо этого они используют копию HTML из памяти (создают так называемый Virtual DOM — дерево из легковесных JS-объектов). То есть, когда вы работаете с помощью реактивного фреймворка, считается корректным, чтобы все изменения на странице работали только через этот фреймворк.
Но стоит добавить метрики и счётчики на сайт, как те в большинстве случаев начинают лезть и самостоятельно менять HTML-страницу. И чем это кончится — хз. Как минимум — корректная работа страницы остаётся под вопросом. Поэтому мы всегда обсуждаем с заказчиками необходимость установки таких штук на сайт.
В целом, все решается. Вот пример переписки с популярной системой маркетинга Flocktory по возможности его подключения на реактивные сайты:
Например, у вас есть JavaScript, который получает на вход, скажем, JSON, а на выходе отдает HTML-страницу. Но это работает в браузере, а нам нужно, чтобы поисковая система получала HTML-файл.
Среди возможных посетителей сайта есть поисковые роботы и есть реальные люди. Когда на сайт приходит реальный пользователь, он получает шаблон с отрисованными JS и HTML. Когда работает поисковый робот, для него мы делаем прослойку, чтобы весь HTML отработал на сервере (используя, например, фреймворк Nuxt. JS). А чтобы так произошло, на сервере нужно поставить тот же JS-движок, который используется во всех современных браузерах, — Node. JS (выдернут из браузера Chrome и вставлен в серверную среду).
Нюанс со сторонними скриптами
Когда заказчик получает на руки сайт, то, в первую очередь, стремится добавить метрики и прочие штуки вроде Google TagManager, JivoSite, MindBox, Retail Rocket. Скорость работы реактивных фреймворков обеспечивается за счёт того, что при изменении страницы они не работают с HTML напрямую. Вместо этого они используют копию HTML из памяти (создают так называемый Virtual DOM — дерево из легковесных JS-объектов). То есть, когда вы работаете с помощью реактивного фреймворка, считается корректным, чтобы все изменения на странице работали только через этот фреймворк.
Но стоит добавить метрики и счётчики на сайт, как те в большинстве случаев начинают лезть и самостоятельно менять HTML-страницу. И чем это кончится — хз. Как минимум — корректная работа страницы остаётся под вопросом. Поэтому мы всегда обсуждаем с заказчиками необходимость установки таких штук на сайт.
В целом, все решается. Вот пример переписки с популярной системой маркетинга Flocktory по возможности его подключения на реактивные сайты:
Дизайн-система
По умолчанию дизайн-система не входит в подарочный комплект дизайна. Мы дарим мини-гайд с основными цветами, шрифтами и парой-тройкой ключевых компонентов (кнопки, ховеры, отступы и т. д.). Это — необходимый минимум, который входит на один-два листа формата А4.
Объём дизайн-системы куда больше. Её смысл в том, чтобы все-все-все элементы, которые есть на проекте, были внесены в так называемые «компоненты». Удобство в том, что если у одной кнопки-компонента на одном макете поменять цвет, то цвет изменится у всех подобных кнопок во всём проекте. Ещё один плюс дизайн-системы — часть страниц можно отдать делать разработчику без необходимости в отрисовке дизайна.
Собирать дизайн-систему стоит, только если отрисован большой объем внутренних страниц. По трудоемкости она занимает ОЧЕНЬ много времени, поэтому актуальна на больших долгосрочных проектах. Например, на тех, где несколько лет подряд шли какие-то доработки / разработки / переработки.
Объём дизайн-системы куда больше. Её смысл в том, чтобы все-все-все элементы, которые есть на проекте, были внесены в так называемые «компоненты». Удобство в том, что если у одной кнопки-компонента на одном макете поменять цвет, то цвет изменится у всех подобных кнопок во всём проекте. Ещё один плюс дизайн-системы — часть страниц можно отдать делать разработчику без необходимости в отрисовке дизайна.
Собирать дизайн-систему стоит, только если отрисован большой объем внутренних страниц. По трудоемкости она занимает ОЧЕНЬ много времени, поэтому актуальна на больших долгосрочных проектах. Например, на тех, где несколько лет подряд шли какие-то доработки / разработки / переработки.
Итого: грамотный план действий по первому кейсу
Во-первых, нужно договориться о дизайне макетов. Затем сделать майндмэп для API плюс проанализировать все макеты от заказчика (откуда какие данные для элементов нужно брать). Дальше, как только дизайн макетов готов, можно приступать к верстке. Когда готова вёрстка (либо параллельно), можно начинать её «натягивать» на реактивный фреймворк (React.JS или Vue. JS). Клиент может хотеть самостоятельно написать API, но тогда сложнее гарантировать консистентность данных. Поэтому, как минимум, это нужно делать с ним вместе («вместе» — значит, за деньги).
Для того, чтобы вести разработку, API сразу не нужно. Сделали mock-объекты, положили файлы с муляжами данных — сделали сайт и интеграцию с mock-объектами. Клиент в это время параллельно готовит свои методы. Подключаете их, всё падает — это неизбежно. Выясняете, где что упало. Следом делаете SSR для поисковых систем и, если клиент хочет много-много всяких метрик и фишечек на свой сайт, решаете с ним по каждому отдельному скрипту, надо или нет.
Для того, чтобы вести разработку, API сразу не нужно. Сделали mock-объекты, положили файлы с муляжами данных — сделали сайт и интеграцию с mock-объектами. Клиент в это время параллельно готовит свои методы. Подключаете их, всё падает — это неизбежно. Выясняете, где что упало. Следом делаете SSR для поисковых систем и, если клиент хочет много-много всяких метрик и фишечек на свой сайт, решаете с ним по каждому отдельному скрипту, надо или нет.
Не переключайтесь, впереди новые кейсы и разборы — чтобы не пропустить, подписывайтесь на Ютуб-канал и заглядывайте в наши соцсеточки.