Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
В последние годы практически все крупные IT-компании заняты созданием экосистем и омниканальных платформ. Есть очень много статей и докладов об их очевидных преимуществах для клиентов и бизнеса, но как это всё устроено изнутри? Как разрабатывать подобные продуктовые решения быстро, гибко и не изобретая велосипеды на каждом шагу? Об этом информации как раз маловато. Вот мы и решили, что белые пятна лучше заполнять историями о собственном опыте, и попробуем сами рассказать, как в ВТБ создавали платформу цифровых продаж.
От хаоса к порядку
Сейчас только и разговоров, что про омниканальность. Это значит, все потенциальные клиенты в процессе поиска нужных им услуг рано или поздно попадают на сайт компании. Так что для нас сайт — основная платформа цифровых продаж. Притом этот сайт у нас не один: ВТБ же не только банк, но и группа компаний, а значит, помимо основного есть ещё порядка 20 сайтов, которые выполняют свои задачи. И всё это кто-то должен разрабатывать.
Обычно в разработке таких крупных сайтов участвуют большие группы людей: сами разработчики, контент-менеджеры, тестировщики, аналитики и т. д. Управляют этим процессом продакт-менеджеры. Бывает, что вовлечены ещё и сторонние подрядчики, которые делают какие-то отдельные куски сайтов. Казалось бы, ну и что такого? Все как-то так и работают, всё получается… Но зачастую при таком подходе ведение сайтов превращается в сборную солянку: разрабы вносят контентные правки, контентщики — правки в HTML-теги, тестировщики и продакты слабо понимают, как это работает, а значит, и как это тестировать. А о релизе в прод и time to market в таких случаях говорить без слёз не приходится. Нередко причина такого безумия кроется и в архитектуре коробочных решений, которыми пользуются крупные компании.
И тут нам бы сказать, что у нас в команде всё было иначе. Но нет: мы тоже не были исключением. Вот только в какой-то момент мы пришли к выводу, что весь этот хаос нужно, наконец, упорядочить. Пора делать собственную платформу!
Ставим цели
Что ж, решить — решили. Какие же цели мы при этом ставили? Они довольно прагматичные и делятся по областям.
Бизнес-цели:
максимально сократить time to market;
предусмотреть возможность легко настраивать и масштабировать страницы с точки зрения SEO и маркетинга;
предусмотреть лёгкую интеграцию сторонних продуктовых решений.
Продуктовые цели:
оптимизировать человеческие ресурсы: разработчик должен заниматься разработкой, а не контентными правками, потому что его время стоит намного дороже;
создать интуитивно понятный интерфейс и продумать максимально простой процесс публикации страниц для облегчения жизни контент-менеджерам, отвечающий при этом всем требованиям информационной безопасности;
обеспечить прозрачность процесса разработки.
Проектирование
Мы с самого начала понимали, что на будущей платформе должны будут собираться все сайты группы компаний ВТБ. Стало быть, она должна быть унифицирована. И тут сами собой возникают два основных момента:
интерфейс наших сайтов, с которым взаимодействуют клиенты;
система управления контентом и сервисами наших сайтов.
Начнём с того, как будут собираться страницы. Мы изучили основные популярные решения, и большинство из них — инструменты визуального редактирования (наподобие Tilda). Этот концепт и взяли за основу. Взаимодействие должно быть максимально простым, поэтому компоненты UI-интереса переносятся с помощью drag’n’drop на страницу, настраиваются и заполняются контентом. Далее настраиваем метатеги и публикуем страницу. Звучит просто, но есть множество нюансов. Давайте разберём их подробнее.
Сейчас любой продукт проектируется в рамках дизайн-системы. Чаще всего это UI Kit, состоящий из атомарных элементов, плюс дизайн-паттерны. Но любой интерфейс у нас состоит из самодостаточных UI-блоков, каждый из которых выполняет свою функцию. Например, Hero-блок ведёт пользователя к целевому действию, карточка продукта подсвечивает основные преимущества продукта и т. д. Мы разделили дизайн-систему сайта на UI Kit и систему виджетов, которые можно назвать бизнес-компонентами.
Бизнес-компонент — самодостаточный элемент интерфейса, выполняющий конкретную бизнес-задачу. В результате контент-менеджеры собирают страницы из бизнес-компонентов, в которых уже всё есть: их нужно просто настроить и заполнить контентом.
Таким образом, дизайн-система делится на два самодостаточных куска — UI Kit (атомарные элементы) и Components Kit (набор бизнес-компонентов). Но тут возникает другая проблема: мы ведь используем одни и те же компоненты и в системе управления контентом, и на самом сайте. Значит, нам необходимо шарить их между первым и вторым. Ну и не будем забывать про принцип DRY (Don’t Repeat Yourself). Следовательно, наши компоненты должны быть пакетами, которые используют обе стороны нашей платформы. Тут нам пришло на ум очевидное решение — сделать их модулями и шарить для обеих систем. И вот уже набор бизнес-компонентов становится третьим большим и самодостаточным куском общей платформы.
А теперь вопрос на засыпку: как же нам шарить компоненты между двумя системами одной платформы? Первое очевидное решение — сделать каждый компонент npm-модулем. Но тут есть недостаток: любое малейшее изменение или исправление бага любого компонента влечёт за собой выкатку публичной и административной частей платформы. А в рамках большой структуры это всё начинает плодить множество проблем, формализма и тому подобных вещей. Так что здесь мы поняли, что необходимо сделать компоненты такими же самодостаточными элементами платформы, и начали мыслить в сторону микрофронтенда.
При проектировании системы управления контентом мы сразу заложили каждый раздел как модуль микрофронтенд-архитектуры с помощью Webpack Module Federation, а также добавили возможность включать/выключать эти модули с помощью Feature Toggle. В результате на выходе у нас всегда один набор артефактов, которые берут все настройки из файла JSON с настройками под конкретный стенд.
Но вернёмся к нашим компонентам. Технология микрофронтенда очень хороша, но всё равно здесь всё завязано на кончиках Webpack или подобных вещах. Мы же хотим, чтобы каждый компонент был как отдельное приложение, которое работает в любом месте — как у клиента, так и на сервере (не будем забывать про SSR, но об этом поговорим далее), и не привязано ни к каким инструментам. И ещё не будем забывать про паттерн Dependency Injection, то есть внедрения внешних зависимостей. Когда каждый компонент сам знает, что ему делать, он живёт как отдельное приложение и ему лишь нужны данные на вход. Мы решили поступить просто — создавать каждый бизнес-компонент отдельным собранным вебпаком приложением (в нашем случае это CommonJS-модуль) и в реальном времени загружать его с помощью лоадера в систему управления или на сам сайт. При этом React, Styled Components и UI Kit являются external-зависимостями для них и живут в одном экземпляре. Это уже даже не микрофронтенд, а нанофронтенд.
Итак, что в итоге: у нас есть сам сайт, система управления контентом и сервисами и система бизнес-компонентов.
Архитектура
Мы описали проектирование нашей платформы. Теперь же время рассказать о другом аспекте — архитектуре. Тут надо добавить, что нам необходимы SEO-оптимизации (где основная — Server Side Rendering).
Если рассматривать процесс пошагово, то выглядит это так. Когда на наш сайт заходит поисковый бот, он получает вёрстку страницы, сгенерированную с помощью SSR, и уходит выгружать её в Big Data и прочие подобные инструменты.
Когда на наш сайт заходит реальный пользователь, браузер получает ту же самую сгенерированную с помощью SSR вёрстку, а далее начинают грузиться скрипты нашего SPA-приложения. При этом мы добавили вот такую оптимизацию: сначала грузится JSON-схема запрашиваемой страницы, далее собираем массив компонентов, требуемых для отрисовки этой страницы, затем загружаем их и начинаем отрисовку. Потом в фоновом режиме мы запускаем загрузку всех остальных бизнес-компонентов. «Зачем?» — спросите вы. А мы просто кешируем и версионируем каждый компонент. То есть когда в браузер загружены все наши бизнес-компоненты, они кешируются в браузере, и далее для мгновенной отрисовки любой страницы нам нужно получить лишь JSON. А если нам необходимо изменить поведение или внести правки в какой-либо компонент, то мы просто повышаем его версию, и браузер понимает, что нужно теперь подгрузить именно её. Таким образом, каждый сайт на нашей платформе — это полноценное SPA-приложение, работающее по тому же принципу, как нативное VK-приложение на телефоне.
Также мы решили позаботиться о пользовательском опыте и добавили на каждую из наших SSR-страниц Skeleton, пока скрипты загружаются и инициализируются. Пользователь получает UX-опыт, будто он взаимодействует с приложением.
Дизайн и фронтенд расписали, а что там осталось? Бэкенд? Ну, тут тоже всё очень просто. Во-первых, нам же не нужно строить интерфейсы и сохранять некую структуру в виде JSON. Во-вторых, сердцем этой системы является React, поэтому мы не стали изобретать велосипед, а просто решили сохранять древовидную структуру с компонентами и любой вложенностью. Мы храним упрощённое дерево компонентов в виде JSON, а бэкенд выступает хранилищем и валидатором данной древовидной структуры. При этом каждый JSON мы парсим и раскладываем по key-value.
Ладно, данная платформа подходит для сборки лендингов и подобных страниц, а как их масштабировать? Гео и прочий зависимый контент. Как интегрировать решения сторонних команд на страницы сайта?
Это всё тоже пришлось предусмотреть. Мы же уже говорили, что контент-менеджер может настраивать каждый компонент. Так вот, мы дали возможность добавлять кастомные параметры, такие как Geo, UTM-метки и тому подобное, и заполнять/изменять контент под эти параметры, а далее массово масштабировать и публиковать. Также любое А/B-тестирование прекрасно ложится под данный механизм. Всё это теперь базовый функционал нашей платформы.
Но как интегрировать решения сторонних команд на страницы сайта? Так как каждый компонент — отдельная сборка, мы можем любое стороннее UI-решение превращать в компонент и использовать на страницах.
Итог
«А где, собственно, лето в Париже?» — спросите вы. Вот всё выше — оно и есть, поскольку так мы решили назвать продукт. На реализацию MVP-платформы ушло три месяца, и мы надеемся, что опыт нашей команды и решения, которые мы задействовали, будут полезны и вам. Делитесь мнениями в комментариях.