Назад в блог

SPA и организация архитектуры проектов

Никита, techlead
Разработка

Изначально мы задумывали этот материал для разработчиков и техлидов, которым надо понимать причину выбора тех или иных подходов. Однако во время написания поняли, что должны объяснить и бизнесовые выгоды. Поэтому текст получился объемным, и его можно разделить на две условные части. 

Первая будет полезна тем, кто до сих пор решает, стоит ли модернизировать свой фронтенд стэк. Мы поделимся собственным опытом перехода от обычной верстки до полномасштабной разработки SPA, расскажем о том, что мы с этого поимели и почему не собираемся назад.

Вторую часть стоит прочитать, если вы хотите знать, как организация архитектуры проектов с помощью SPA влияет на финансовые показатели и привлекательность для клиентов с точки зрения бизнеса.

Начнем с истории от нашего техлида, Никиты Толкачева, он расскажет, как улучшились рабочие процессы внутри команды, на какие нюансы стоит обращать внимание, если вы задумали осуществить такой же переход и почему вам это понравится.

Вот уже как несколько лет все наши проекты мы разрабатываем как SPA, они же одностраничные приложения, они же сайты, где навигация происходит без перезагрузки страницы, а кнопка назад не работает. Как мы до такого докатились и почему до сих продолжаем?

Предпосылки к изменениям

Мы начали приглядываться к фронтенд фреймворкам где-то в 2015 году, на пике ажиотажа вокруг реакта. Почему? Кроме хайпа и страха остаться позади конкурентов, существовали и реальные проблемы.

Поскольку мы занимаемся только кастомной разработкой, бэк-офис всех проектов представляет из себя самопис. Сложность страниц бэк-офиса варьируется: от простых CRUD’ов, до сложных рабочих панелей. Такие панели, зачастую, изобилуют интерактивностью и динамичностью.

Так как это аутсорс, нужно уметь делать быстро и хорошо одновременно. Какие здесь проблемы?

Простые CRUD'ы на то и простые, что проблем с ними особо не было. Разве что всякие datepicker'ы, ajax select'ы искать, да такие, чтоб между собой не конфликтовали и смотрелись хорошо. По памяти, с этим особых трудностей не было, разве что после подгруженного ajax'ом контента нужно было всю эту кипу плагинов заново дергать.

А вот штуки посложнее всегда получались тяжко. Хранение состояния напрямую в DOM'е, императивное его изменение, логика, разбросанная то тут, то там по обработчикам событий... В общем, тяжко.

Пытливый читатель может заметить, что это не столько проблема инструментов, сколько проблема подхода (все видели редакс, написанный в твитт, да?) – и будет прав! На тот момент, о таких подходах известно нам не было (да и не только нам, судя по не столь давнему появлению официальных, напоминающих реакт, либ для Android и iOS).

Поэтому основное, что нам дал реакт – новое представление о фронтенд разработке в целом. Декларативность, компоненты, управление состоянием, функциональщина – все это было новым и интересным, было ясно, что это шаг в нужную сторону.

Проблемы старого подхода

В начале стоит сделать ремарку о том, как у нас раньше распределялась работа между людьми.

Выделялось 3 роли:

  • Дизайнер. Дизайнит.
  • Верстальщик. Занимается версткой лицевой части проекта (сайта). Результатом его работы является HTML + CSS + минимальный JS.
  • Программист. Человек, который пилит бэкенд, пилит бэк-офис (туда верстальщики не предлагались, т.к. для верстки использовались бутстрап шаблоны) и "программирует сайт". Под программированием сайта имеется в виду натягивание верстки на бэк + какая-то логика на JS, если есть (слайдеры, например, не считаются логикой, и ими занимался верстальщик, а какой-нибудь, условно, калькулятор – логика, ей должен заниматься программист).

Поскольку логика на JS падала на руки программистов, именно они и начали постигать азы фронтовых фреймворков первыми. Время шло, кроме реакта в нашем арсенале появился Vue, экосистемы разрастались, росло количество материалов для обучения. Проблемы со сложностью разработки и поддержки логики фронта потихоньку сводились на нет, а вслед за ними, как это обычно бывает с проблемами, начали выявляться другие.

Во-первых, некоторым верстальщикам становилось скучно. Хотелось изучать что-то новое, двигаться дальше, да вот непонятно куда. Без знания бэка довольно сложно натягивать верстку. Бэк-офисом заниматься тоже не вариант. Единственное развлечение – прокачивать JS и пилить логику на сайте, где это возможно.

Во-вторых, натягивание верстки было реально узким местом разработки. То там ссылку забыли проставить, то там ненужный класс добавили, то какой-то блок вообще потерялся.

В-третьих, были те, кто вообще не хотели касаться фронта. Представим их суровыми бородатыми дядями, которые плевались от HTML и JS за язык не считали.

"Скучно" и "плевались" – не очень тянули на объективные проблемы, может, дело было в людях, а не в подходе. А вот "реально узкое место" – довольно таки объективно. Как будем решать?

Плюсы от модернизации фронтенд разработки

Собственно, в нашем случае, решением данных проблем и стали SPA.

  • Стало возможным разделить бэкенд и фронтенд. Суровые дяди в восторге, гоняют себе из базы в JSON и спят спокойно.
  • Для ребят на фронте открылся целый новый мир.
  • Проблема с переносом верстки так же решилась, поскольку, переносить больше нечего. Считайте, на одну причину багов стало меньше.

JS верстальщикам был знаком, компонентный подход давался проще из-за БЭМа. Не без сложностей, конечно, но мы натаскали ребят до, теперь уже популярного термина, "фронтенд-разработчик". Наши "программисты", которые застали появление фронтовых фреймворков в компании, теперь именуются "фулстэк разработчики" (да-да, шутка про то, что это те, кто верстать не умеют), а суровые бородатые дяди – "бэкенд разработчики". Дизайнеры остались дизайнерами :)

С каким сложностями пришлось столкнуться?

Во-первых, помимо бэкенд-сервера, появился еще и фронтенд-сервер – node.js-приложение, обеспечивающее SSR. Для тех, кто до сих пор деплоит ручками, это может быть неудобно. Плюс, нужно быть готовым к увеличению нагрузки на сервер, т.к. SSR – недешевое удовольствие. Можно кэшировать страницы целиком, т.е. поставить кэширующий прокси перед node.js, но в таком случае нужно разграничивать то, что вы будете рендерить на сервере (публичный контент, который доступен и одинаков для всех) и то, что вы будете рендерить на клиенте (что-то приватное, например, состояние авторизации в шапке, корзина). 

Еще одной проблемой может быть то, что node.js-приложения – однопоточные, поэтому нужно уметь поднимать сразу несколько процессов и балансировать нагрузку между ними.

Во-вторых, API и документация. Фронтенду и бэкенду нужно как-то между собой взаимодействовать, причем схему их взаимодействий желательно описывать и поддерживать в актуальном состоянии. Мы решаем это написанием OpenAPI спеки. В некоторых экосистемах существуют хорошие генераторы как самой спеки, так и клиента/сервера из нее, что может быть удобно и следует иметь ввиду.

В-третьих, раздутый размер JS на проекте. Нужно следить за подключаемыми библиотеками, уметь code-splitting, lazy-loading.

Теперь перейдем к части, которая должна заинтересовать непосредственно предпринимателей. Ну или тех, кто считает рентабельность проекта. Ее подготовил Максим Бонцевич, директор студии.

Как изменения отразились на клиентах?

Во-первых, мы получили единое API для приложения, сайта и виджетов. Это особо удобно для проектов, которые будут в дальнейшем масштабироваться, пусть и не в ближайшие сроки. 

Имея серверную часть, представленую задокументированными методами API, на которой выполняется основная логика и бизнес-процессы, интегрировать еще один сайт, приложение или сторонний виджет не представляет сложности — все будет объединено в одну экосистему. 

Во-вторых, мы смогли увеличить скорость работы сайта, потому что при переходах по страницам он загружается не целиком заново, а только его обновившаяся часть, например, дополненная корзина. 

Еще, благодаря такому подходу, стало возможным асинхронно подгружать тяжелые в расчетах блоки. Например, подборку похожих товаров. Пользователь сначала видит основную информацию — выбранный товар, а потом по готовности асинхронно загружается блок с рекомендациями.

Другой плюс от использования нового подхода — возможность применять кэширование на стороне клиента. Так, когда вы захотите в браузере вернуться назад, повторные запросы к серверу отправлять не придется. Да и одни и те же картинки не будут каждый раз “скачиваться”. Экономия трафика и времени, так приятные для клиентов.

Сайты на SPA проще масштабировать при больших нагрузках. Например, когда надо разнести эту нагрузку на несколько серверов. 

Еще стало очень удобно выносить логику на клиентскую часть, в браузер. Это заметно, когда, находясь в корзине, вы меняете количество товаров, после чего нужно обновить “итого”, чтобы увидеть новую стоимость всех покупок. Если делать все расчеты на клиентской стороне, они будут происходить мгновенно. Именно так работают отзывчивые интерфейсы. 

Однако есть у клиентов и страх, что сайт сделанный на React, Vue нельзя продвигать. Он ничем не подкрепляется. Для поисковиков это такой же обычный сайт благодаря тому, что мы делаем его в SSR.

Почему SPA лучше чем сайт, сделанный на Битриксе?

Оговорюсь сразу, что сравнивать разработку на Битриксе и разработку как SPA не совсем корректно, потому что SPA — это, скорее, подход, а Битрикс — инструмент.

Я знаю, что ребята, которые работают на Битриксе тоже пытаются выстраивать что-то похожее на SPA, но готовые CMS не заточены под подобную разработку, поэтому сделать аналогичный проект с помощью этого инструмента сложно. Зачастую приходится использовать кучу костылей, чтобы задуманное работало.

Но какой серьезный проект, нацеленный на масштабирование, сможет удержаться на костылях? Да никакой. При более-менее крупных обновлениях костыли “полетят”, и все сломается. Поэтому со временем придется больше внимания уделять латанию старых дыр, а не разработке нового функционала.

Отсюда вытекает классический вопрос: “Делать с нуля все или использовать пакетные CMS?” 

Готовые CMS хороши для базовых проектов со стандартным функционалом. И спорить нечего. Разработка из с нуля будет дольше и дороже. Но такие базовые проекты не для нас. Мы любим большие вызовы, амбиции и планы на будущее. 

Да, с готовой CMS вы получите изначально объемный функционал, который, может быть, закроет даже все ваши текущие потребности. Но, очевидно, что со временем вам захочется что-то кастомизировать под себя, интегрировать сторонние системы или решить какие-то новые проблемы (появление кучи удаленных сотрудников во время covid, перевод бизнеса полностью в оффлайн и т.п.). Тогда придет время вспомнить про эту статью. И то, что развитие проекта нужно предусматривать на моменте создания.