Любой успешный проект рано или поздно вырастает из маленького лампового стартапа в большую неповоротливую штуку с кучей легаси кода. В условиях высокой конкуренции важную роль играет скорость внесения изменений в продукт. Из двух альтернатив — сделать правильно, потратив много сил, или сделать дешево и сердито — редко кто выбирает первую. И тут на помощь приходят костыли. При этом нарушается целостность идеи проекта, теряется стройность архитектуры. Со временем темпы развития продукта падают, а стоимость поддержки растет.
Можно решать эти проблемы, двигаясь небольшими шагами, внося улучшения постепенно. Альтернативный вариант — все стереть и написать заново. На это тяжело решиться, ведь требуется выделить ресурсы, которых всегда не хватает. Также есть риск навредить уже работающему продукту. Однако, мы решились и в своем докладе я расскажу:
- Что такое реинжиниринг и зачем он был нужен в tutu.ru.
- Как мы подошли к выбору нового технологического стека.
- Как мы выбрали архитектуру новых приложений.
- Почему мы пришли к TypeScript и React.
- Шаблонизатор для компонентов Reactа, серьезно?
- Выкидывать legacy код жестоко, но нужно же с ним что-то делать.
- Как удовлетворить seo без лишних усилий.
2. 230сотрудников
13.5 млнпосетителей в месяц
2003год основания
600 тыспосетителей в день
О Туту.ру
Авиабилеты Ж/д билеты Туры Гостиницы Электрички
8 млнстрок кода
12. Требования к новой системе
• Получить платформу для быстрого развития
• Выдавать результаты поэтапно
• Не навредить работающему продукту
• Не навредить позициям в поисковиках
• Сохранить прибыльность
Постоянное изменение внешних факторов
нужно адаптироваться, чтобы выжить
Делать быстро, переделывать часто
быстро меняться, пробовать новые фичи
Применяются «быстрые», а не «правильные» решения
Обрастаем костылями
Рост количества сотрудников
Рост объема кода
Весна 2013
Эксклюзивный летний поезд
Ожидания: подключим быстро и начнем продавать
Реальность: по оценкам подключились бы к концу лета
Тяжелое наследие full stack разработки
Появились какие-то ресурсы
Обнаружилась сильная связанность модулей
Из-за этого изменения в одном тянули изменения в другом
Нужно было тратить больше ресурсов, чем предполагалось при оценке
Не было выделенной команды, разработчики переключались на продуктовые задачи, которые были важнее
Нет фокуса на конечной цели процесса
Все это привело к низкой скорости, толку было мало, Изменения происходили медленно
Есть опыт, знаем актуальные требования, недостатки текущего решения, экспертиза в предметной области
Можно спроектировать более гибкую систему «с нуля»
Такую, чтобы не пришлось опять переписывать
Выделим специальную команду
Будет фокус на конкретных целях
Платформа для быстрого развития
Выход на новые рынки
Мобильная версия
Поэтапное получение результатов
Не можем ждать год первые результаты – мир меняется быстро
Не навредить работающему продукту
Живем на то, что заработали
Не навредить позициям в поисковиках
SEO продвижение играет значимую роль в успехе компании
Разрубили клубок
мухи отдельно, котлеты отдельно
Можно модифицировать независимо, чтобы в будущем не пришлось еще раз проводить реинжиниринг
В итоге, реинжиниринг затронул и бэкенд, но я буду рассказывать об изменениях во фронтенде
TypeScript - вот это все, а еще и…
Статическая типизация
Legacy-friendly!!! Не все смогли начать с ним работать, но нам удалось преодолеть проблемы. Для легаси модулей пишем d.ts файлы
M$
babel
Еще не родился
+ модульная система RequireJS
Переиспользуемые Компоненты!
Шина событий
flux понравился и подошел
П - прагматичность
Но верстальщики выросли и стали полноценными фронтенд-разработчиками
Хочется переписать совсем все, но
Это потребует больше ресурсов на разработку, чем нужно
Больше ресурсов на тестирование, чем нужно
А лучше делать что-то нужное, чем что-то ненужное
Как понять, что надо переписать?
Цель – переписать код, чтобы развиваться
Смотрим, где скорее всего будут доработки
В дальнейшем – перепишем все
И - итеративная разработка
Переписываем только критические вещи, оставляя то, с чем можно жить в legacy
Standalone вариант – nodeJS
Интегрированный в backend среду – php v8js
Мы выбрали phpV8, т.к. имеем php инфраструктуру
он решает задачу и не требует развертывания дополнительной инфраструктуры
Есть ограничение – нет доступа к npm пакетам, но мы в данный момент ими не пользуемся в приложении
Возможно, со временем мы придем к nodeJS, но прямо сейчас нас устраивает и phpV8
Собираем самодостаточный бандл,
к нему подкладываем эмулятор загрузчика модулей (они уже есть в бандле) и данные с бэкенда
бандл каждый раз выполняется на сервере, отдает строку
Выбор элементов стека происходил потапно
Но мы не старались отслеживать новинки и переезжать сразу
Версия реакта 12->13, потом долго жили на 13. сейчас 14 и пока не торопимся обновляться
Главный вопрос – зачем? В чем польза? Если можем аргументировать, делаем.
Иначе делаем что то полезное
Уходим от ReactTemplates (новые на jsx, не бросаемся переписывать)
Мигрируем на webpack
В перспективе отказываемся от jquery
И - Итеративность
Аналитика: обратный инжиниринг
В процессе натыкаемся, что старая версия работает не так, как должно быть
Никто не знает, как правильно, спросить уже не у кого
Выделяем модули, оцениваем их вариативность
Перерабатываем поведение системы –
упрощаем и исправляем ошибки
становится проще разрабатывать новые фичи
Разработка – Выбираем миниммальное необходимое решение для текущей задачи,
не фантазируем, что еще потом здесь может понадобиться
иначе можем потратить время, а оно и не понадобится, или понадобится другое
Аналитика: обратный инжиниринг
В процессе натыкаемся, что старая версия работает не так, как должно быть
Никто не знает, как правильно, спросить уже не у кого
Выделяем модули, оцениваем их вариативность
Перерабатываем поведение системы –
упрощаем и исправляем ошибки
становится проще разрабатывать новые фичи
Разработка – Выбираем миниммальное необходимое решение для текущей задачи,
не фантазируем, что еще потом здесь может понадобиться
иначе можем потратить время, а оно и не понадобится, или понадобится другое
Тестирование – не идеальный вариант, а приемлемый уровень качества, дающий нужный уровень конверсии
Аналитика: обратный инжиниринг
В процессе натыкаемся, что старая версия работает не так, как должно быть
Никто не знает, как правильно, спросить уже не у кого
Выделяем модули, оцениваем их вариативность
Перерабатываем поведение системы –
упрощаем и исправляем ошибки
становится проще разрабатывать новые фичи
Разработка – Выбираем миниммальное необходимое решение для текущей задачи,
не фантазируем, что еще потом здесь может понадобиться
иначе можем потратить время, а оно и не понадобится, или понадобится другое
Тестирование – не идеальный вариант, а приемлемый уровень качества, дающий нужный уровень конверсии
Платформа
Запилили мобильную версию на основе десктопной, заменив вьюшки
АПИ для мобильного приложения
Как бонус, вычистили кучу краевых случаев и непонятностей
Саксесс-страница: раньше боялись влезать, переделка занимала несколько месяцев – теперь постоянно проводятся улучшения и тд