
Начало
Это может прозвучать необычно, но развитие полноценных веб-приложений фактически началась с фронтенд-технологий. До разделения кода систем на фронтенд и бэкенд все они были как бы разновидностью сайтов, но с более сложными процессами, выполняющимися “на сервере”. На каждый запрос пользователя, сервером ему отдавался новый документ с такой же шапкой и подвалом. За редким исключением эти интерфейсы выходили достаточно примитивными, ведь каждое действие пользователя заставляло систему сначала немного подумать, и затем нарисовать новую страницу для результативного состояния. Значительные манипуляции с содержимым страницы в браузерах обычно были крайней непроизводительными, да и оказывались сложны для реализации. Изначально HTML-сайты или Web задумывались как упрощенный вариант издательской системы, в основе которой лежала идея "гипертекста” с переходами от одних страниц к другим через ссылки.

Предпринимались, впрочем, и некоторые попытки преодолеть слабую развитость браузерных технологий, используя так называемые Rich Internet Applications(англ. - Развитые интернет-приложения), которые представляли собой обособленные приложения, встраиваемое через плагин браузера, типа Java Applets или Flash/Flex, работающие в собственной изолированной области и обменивающиеся данными с серверами. Но выстрелившие “умные” мобильные устройства их похоронили, потому что работа Rich Internet-приложений быстро опустошала заряд аккумуляторов, да и их интерфейсы обычно были не очень хорошо приспособлены к разнообразию мобильных экранов.

Эта началось с популяризации устройств с большими экранами Apple: плееров IPod, телефонов IPhone, планшетов IPad, предназначавшихся для постоянного использования. Большие цветные экраны и яркие интерфейсы, приспособленные для работы пальцами, создавали повышенные требования к аккумуляторам, даже несмотря на то, что мобильные процессоры были еще относительно маломощными. Работа в них приложений-блобов начала создавать множество проблем в использовании, и эстафета перешла к технологиям, работающим непосредственно в браузерах или мобильных операционных системах. Особенностью архитектуры этих технологий было соответствие экранов - виртуальным подстраницам, т. е. они так или иначе напоминали находившиеся в это время на пике популярности MVC-фреймворки.
SPA-приложения
SPA(Single Page Application - англ. Одностраничное приложение) фреймворки, такие как Angular2+, React и Vue по своему устройству все еще напоминают RIA. Они реализуют свои собственные механизмы рендеринга в определенные области или, чаще всего, только одну точку монтирования веб-страницы, и приложения работают изолированно внутри неё точно так же, как это происходило в RIA. Фронтенд приложение берет на себя и роутинг, и обработку действий пользователя, оставляя серверам только роль поставщиков данных. Если раньше, во время приложений-вебсайтов, каждый новый экран появлялся у пользователя практически целиком построенный сервером, то теперь отрисовка выполняется пользовательским браузером. Также и код приложения теперь состоит процентов на 80 из фронтенд-технологий. Сервер-сайду остается только формирование структур данных из СУБД, часто даже бизнес-логика работы с которыми реализуется на стороне браузера, как в GraphQL, протоколе определения состава получаемых или изменяемых данных на клиенте, или HEATEOAS, протоколе абстракции клиент-серверного взаимодействия. Сами по себе эти технологии, конечно, не обязывают выполнять джойны и мапинг структур данных в браузерном контексте, но в реальном применении rich-клиентов это оказывается практически неизбежно. Для того чтобы процессинг данных не блокировал браузерный UI-поток фронтенд-фреймворки обзавелись различными решениями такими как store-подсистемы, файберы и async.
Архитектура SPA привнесла сразу несколько улучшений:
Приложения на новых фронтенд-технологиях выглядели, в основном, красивее, т. к. использовали все новые достижения браузерного развития и не тащили груз прошлого.
Разделение на фронтенд и бэкенд позволило подключать другие виды фронтендов или клиентов, например мобильные приложения или другие приложения, требующие интеграции с данными и процессами целевой системы. Требование к модуляризации происходило не только из развития технологий, но и от роста количества эксплуатируемых информационных систем.
Интерфейс отрисовывался быстрее за счет того, что часть логики выполнялась на локальном компьютере пользователя, и изменения не всегда требовали обмена данными с серверами, а запросы выполнялись только для получения или изменения данных, а не рендеринга страниц целиком.
Приложения на фронтенд-технологиях стало удобнее масштабировать, потому что для рендеринга интерфейса можно было выделить статические серверы или даже сторонние сервисы, отдающие ресурсы чрезвычайно быстро и менее зависимо от состояния серверов владельца.
Сложность интерфейса и даже бизнес-логики теперь стала проблемой на стороне пользователей. Тут действительно есть объективные сложности. Концепция MVC слишком примитивна, чтобы оптимально описывать сложные состояния экранов. Технически интерфейс обычно работает в одном потоке, и если занять его какой-то продолжительной и “тяжелой” задачей без специальных ухищрений, то это может заблокировать интерфейс браузерной страницы, и она, как бы, подвиснет. Поэтому появились разные store-подсистемы, выполняющие работу с данными псевдо-асинхронно.
Чтобы еще ускорить отрисовку появилась, также, концепция серверного рендеринга фронтенд-элементов, который мог ускорить первичный или выборочный рендеринг страниц, а изменения в ответ на действия, вычислялись уже в браузерах пользователей.
Кроме того, браузеры работали так, что ограничивали количество одновременных запросов на хост и выполняли их последовательно. При этом серверы фуллстек-приложений имели свои ограничения по ресурсам и масштабируемости. Поэтому вместо подключения большого количества ресурсных файлов: скриптов, картинок и стилей - было эффективнее их склеивать в большие бандлы и размещать на быстрых CDN-серверах специализированных провайдеров.
Преимущество веб-приложений, построенных вокруг фронтенд-технологий, усилилось с появлением универсальных кластерных решений, которые позволили настраивать динамическое масштабирование. Появилось ощущение, что множество мелких отдельных сервисов будут работать лучше, чем один большой “тяжелый” монолит.
Однако, по мере развития проектов оказалось, что SPA-приложения также быстро, может быть даже еще быстрее, превращаются в такие же неповоротливые монолиты, которые долго собираются из исходных кодов и запускаются, а попытки их модуляризировать приводят к значительному усложнению разработки. Возникает проблема взаимодействия между модулями, когда они расположены на одной странице или составляют различные части одних и тех же процессов.
Если у вас несколько rich-клиентов, например отдельные версии под разные платформы возникает проблема синхронизации логики и протоколов между ними. Генераторы API по документации и версионирование ендпоинтов конечно помогают с этими проблемами справляться, но за счет своих накладных расходов.
Со временем у всех начинаются проблемы с согласованностью версий модулей, и разработчикам остается обратно бежать в монорепу или иерархический проект, в котором модульным можно назвать только какие-то отдельные аспекты на уровне артефактов или рантайма, т. е. все равно фактически получается монолит.
Фронтенд-приложения без модуляризации обычно довольно сложно кастомизируются, что может быть приемлемо если вы делаете свой сервис-единорог, но никак не подходит, если пытаетесь поставлять что-то вроде тиражируемого продукта. Потому что вам в этом случае придется уговаривать заказчиков подстраиваться под уже реализованный ранее другим образом функционал либо хоронить поддерживаемость, добавляя везде if-else для каждого заказчика. Что может быть реалистично только пока собственные пожелания заказчиков достаточно скромны, и они лояльны к вашему продукту, а не к конкурирующим аналогам.
Усложняет разработку и тот факт, что приложения, разрабатываемые на популярных фронтенд и бэкенд технологиях, чаще всего, представляют собой уникальные технологические решения, адаптация к которым специалистов других подобных систем может быть затруднена. Например, для разработчика на Spring довольно неочевидным может оказаться культура разработки фронтенд-части того же проекта на фреймворке Vue, поскольку архитектурно и технологически они очень мало похожи между собой. Даже если взять только популярные фронтенд-фреймворки и сообщества их разработчиков, то можно увидеть крайне мало точек соприкосновения, переиспользования и подходов к разработке. Поэтому для разработчика переход с одного фреймворка на другой будет понижать его уровень владения технологиями со среднего до начального. Сочетание различных фреймворков в одной экосистеме порождает скорее конфликтные модели взаимодействий, чем кооперативные.
За время переписывания старых приложений на SPA-фреймворки, браузерные технологии продвинулись далеко вперед, в том числе усваивая опыт развития фронтенд-фреймворков, иногда даже прямо заимствуя решения, разработанные для других обстоятельств, вроде хардкода строк шаблонной HTML-like разметки в JavaScript коде.
Программные интерфейсы браузеров для фронтенд-разработки, первоначальная скудность и примитивность которых привела к появлению огромного множества фреймворков, теперь стали гораздо мощнее и удобнее для разработки. Появились технологии и стандарты компонентной и модульной организации кода, шаблонизации и инкапсуляции поддеревьев веб-элементов. Все это могло бы поставить перед разработчиками вопрос: а не стали ли уже популярные фронтенд-фреймворки такими же устаревшими, как те технологии, которые они вытесняли все это время?
Вокруг веб-компонентов существует некоторая неопределенность или даже противостояние, заключающееся в вопросе каким путем сторонний код может переопределять базовые компоненты. Одна партия, кажется, считает, что правильным будет иметь возможность унаследовать и переопределить любой браузерный элемент, а другая, похоже, находит правильным разрешить только дополнять поведение стандартных элементов за счет механизмов похожих на плагины и хуки.
Развиваются также и новые стандарты и протоколы взаимодействия серверов с браузерами делая модульный код более эффективным, чем монолитный не только в гибкости, но и в плане производительности.
Кубернетизация
Появление универсальных технологий кластеризации, таких как k8s, потребовали участия в процессах разработки веб-приложений новых бригад специалистов или DevOps-инженеров, добавив приложениям еще 3-4 слоя абстракций только для управления конфигурациями.

Само по себе кластерное ПО капризно и сложно в поддержке настолько, что типичным решением проблем стало пересоздание всего кластера “с нуля” и версионирование с фиксированием всех изменений в конфигурациях. Не уверен, что это или, например, не удаляющийся никаким способом под это нормальная ситуация для продуктивных сред, кажется, сейчас уже выстраивают отказоустойчивые системы уже из самих кластеров.
Кроме того, реальная работа систем в этих кластерах кажется немыслимой без внедрения дополнительных пристроек для обеспечения обозреваемости, трассировки, логирования.
Все это усугубляет проблемы разделения айтишников на специализирующихся на фронтенде, бэкенде или конфигурациях и создает дополнительные сложности при реализации новых фич и исправлении старых багов, обусловленные, как минимум, коммуникативными издержками. На многих популярных размасштабированных ресурсах вполне очевидные баги не исправляются годами и значительных улучшений пользовательского опыта давно не происходит. Их интерфейс до сих пор разделен между мобильными и десктопными версиями фронтендов и представляют по сути конкурирующие независмые проекты. Все это происходит от того, что сферы ответственности не покрывают отдельно взятых фич целиком, которые состоят из фронтенд, бекенд, DBA и инфраструктурных разработок. В такой ситуации никто ни за что как бы не отвечает, да и не может реализовать если по одной из сфер есть блокеры.
На порядок выросли и системные, т. е. аппаратные требования: если отдельно взятые сервисы казались значительно “легче” огромных монолитов, то, когда появились полнофункциональные системы, даже функционально простые системы стали “жрать память”, как крупные монолиты. Например, порядочный реестр образов для kubernetes требует от 4Gb оперативной памяти, что раньше казалось внушительным объемом и могло быть характеристикой сервера, обслуживающего пользователей большой организации, а сейчас пустой кластер стартует примерно от 10Gb. Популярный реестр образов Harbor еще от 4х, мониторинг - еще пара гигабайт. Все это - что бы запускать скрипты на питоне по 50Мб.
Деградировала и технологическая культура: если раньше веб-приложения позволяли менять конфигурации, закрывающие широкие спектры потребностей “налету”, что давало возможность, например, отладить какую-то проблему точечно, повысив детализацию логирования только на отдельных участках системы, то с продвижением кластерных технологий закрепились варианты через хардкод этих значений “в коде”, требующие перезапуска контейнера с сервисом, а иногда и всей группы связанных приложений после каждого изменения.
Все эти сложности требуют большого количества квалифицированных специалистов вкладывающее значительное количество времени и денег, что превращает каждую компанию, связавшуюся с автоматизацией инфраструктуры, фактически в ИТ-компанию. По крайней мере, все крупные организации сразу обзавелись своими ИТ-дочками, когда раньше хватало одного отдела.
Решение проблемы инфраструктурной сложности сейчас находят в том, чтобы разрабатывать обособленные приложения из одних и тех же шаблонов, непосредственно связанные, в первую очередь, аутентификационными механизмами. Но мы то знаем, что это равнозначно тому же копипасту, который, когда вам снова потребуется смигрировать один из компонентов архитектуры на что-то более подходящее к новым реалиям, например ту же СУБД, будет выстреливать в ногу. Потому что наследование работает там, где возможна абстракция, а для рецептов развертываний маловероятно получить такой уровень унификации. Кроме того, изменять что-то в базовых скриптах никто не осмелится, там ведь нет даже типобезопасности и средний уровень надежности такой, что кажется лучше не трогать ничего и никогда. Там, где раньше челендж был чисто технический теперь он становится еще и бюрократическим.
Генерация
Да и с техническим вызовом все стало не так просто, сможет ли ваш разработчик или даже искусственный ассистент сконвертировать реальное приложение, написанное на React в Angular или Vue? Сколько токенов сожрет этот процесс и насколько результат будет адекватным? А что если это будет не фреймворк из популярной тройки, а какая-то новая технология, для которой никто не будет обучать LLM, пока она не “выстрелит”? А она не выстрелит пока не появится во всех популярных кодирующих ассистентах. Почему так может случиться в реальности? Отчасти это потому, что популярные ныне фронтенд-фреймворки появились и завоевали рынок до стандартизации компонентной модели фронтенда в браузерах. Поэтому они представляют собой шкаф, который падает давно и долго, как это было с уходом браузера Internet Explorer. Многие использовали его “придерживаясь выбора большинства”, но однажды это все таки произошло несмотря на то, что он начал показывать хорошие темпы развития.
Кодирующие ИИ-ассистенты могут неплохо справляться даже с не очень распространенными технологиями, если они заточены на это и удалось подобрать удачный промт, но справится ли они с бизнесовым кодом, имеющим значительный технический или архитектурный долг или неявную смысловую связанность?
Место для недорогой разработки, решающей прикладные задачи бизнеса, сейчас оказалось под вопросом. Может ли сейчас один "программист” сделать все веб-приложение или систему сам, вплоть до выкатки в продуктивные среды, даже имея под рукой не заблокированный качественный искусственный интеллект?
Сейчас предлагается подход, когда ассистент берет на себя генерацию кода, а специалист лишь корректирует результаты. Но при таком подходе весь траблшутинг лежит на том же специалисте, а чтобы решать проблемы в 5-10 различных областях (фронтенд, бэкенд, базы данных, серверы и кластеры, аналитика) необходимо иметь недюжинный собственный опыт в разработке, получение которого осложняется, когда за вас всю работу выполняют ассистенты ИИ. А они, в свою очередь, решают какую-то часть популярных, типовых или базовых задач, но остается некоторая доля харкдкора, с которым ИИ не справляется, и специалист остается со стеной один на один.
Таким образом, даже сократив число языков программирования, которые задействованы в контексте отдельно взятого проекта, можно помочь себе справляться с задачами. Особенно учитывая, что разнообразие технологий перестало быть катализатором их развития и улучшения.
Суммируя
Давайте рассмотрим все плюсы и минусы систем рассматриваемых подходов сравнив "за" и "против" наглядно в следующей таблице.
Старый монолит |
Фронтенд + Бекенд |
Микросервсы |
|
Преимущества
+ Относительно простая настройка окружений разработки и продуктивной работы приложений + Разработка, затрагивающая разные подсистемы архитектуры может получаться проще + Проще реализовать и использовать транзакционность |
Преимущества
+ Создавать новый код гораздо проще, чем поддерживать. За счет чего первый шаг через MVP гораздо доступнее + Можно разрабатывать разные фронтенды и клиенты для одного бэкенда + Можно кластеризовать отдельно + Фронтенд серверы хорошо справляются с нагрузками за счет оптимизаций и кеширования
|
Преимущества
+ Можно использовать и переиспользовать сервисы и приложения на разных технологиях + Унификация и переиспользование инфраструктурной работы и архитектурных решений
|
|
Недостатки - Интерфейс более примитивный, особенно в плане динамического обновления состояний компонентов - Навигация по коду затруднена с самого начала: нелегко найти соответствие между адресом экрана в браузере и отвечающими за него участками кода - По мере роста усложняется развитие и эксплуатация - При использовании разных стеков нет унификации конфигураций и деплоймента. Этими знаниями часто владеет один незаменимый сотрудник. |
Недостатки - Быстро превращается в трудноподдерживаемый монолит. В основном возможен только MVC, который весьма ограничен в возможностях отображения сложных состояний(вкладки, фильтры, панели). - Много усилий может тратиться на координацию между приложениями фронта и бека, а также между их разработчиками. Требуется генерировать или прорабатывать API, согласовывать его изменения или организовывать мультиверсионность, полагаться на коммуникации и бюрократию проектного управления. - Культура фронтенд-разработки относительно низкая: в сообществах разработчиков популярны идеи отрицания ООП, IoC и других признанных паттернов разработки, изобретение своих map-reduce реализаций для однопоточного браузерного UI-рантайма, предпочтение хардкод решений, борьба с ветряными мельницами
|
Недостатки - Не переиспользуются ресурсы рантаймов, каждое приложение - черный ящик со своими копиями библиотек, иногда базами данных или статически собранным кодом. - Сложно разрабатывать, отлаживать, поддерживать и развивать инфраструктуру, соблюдая версионность и консистентность между составляющими. - Кластерные системы хрупки и сложны настолько, что требуют специального штата поддерживающих специалистов. - Многие “паттерны” для решения типичных проблем распределённых архитектур превращают их в практический монолит - Размазывая приложение на кластер, мы получаем технологическую и функциональную деградацию его компонентов: "простые" языки и фреймворки, ориентированные на хардкод, отсутствие фич, требующих высокого уровня интеграции. Например, переключение уровней логирования и изменение конфигураций на лету без перезапуска контейнеров. - Уровень безопасности может быть не самым высоким (обычно данные между клиентом и сервером пересылаются в открытом формате), если не вкладываться в него специально. Этот формат может быть исследован и взломан, в т.ч. роботами. Контейнерные системы не сертифицируются на высокие уровни безопасности. - Сложно реализовать полноценную отказоустойчивость с сохранением состояний пользовательских сессий и транзакционностью. См. Теорему CAP. |
Современные инфраструктуры привнесли больше сложности и стали значительно дороже, как будто в угоду интересам облачных провайдеров и производителей оборудования. Однако, фарш назад не провернешь и конкурировать с подобными системами можно либо в специализированных нишах, либо решая бизнес-задачи с изрядной долей рационализма и грамотности.
Актуальные требования к веб-платформе для бизнеса
Современная веб-технология для разработки корпоративных бизнес-приложений должна удовлетворять следующим требованиям:
Обеспечивать интегрированную, консистентную и гомогенизированную среду из технологий для производительной разработки и эксплуатации, позволяя легко “кастомизировать”, т. е. изменять поведение в производном коде сохраняя переиспользование и без доступа к оригиналу. Также подразумевается значительное использование стандартов, технологий и решении сторонних вендоров.
Позволять использовать инструменты кодогенерации и автоматизации в процессах разработки, сохраняя при этом возможность управления кодом и артефактами “вручную”.
Обладать сбалансированной сложностью и набором инструментов для эффективного решения бизнес-задач, такими как конфигурируемость, производительность и готовность к интеграции с другими системами. Это должно позволять вводить в эксплуатацию приложения в обозримые, оцениваемые и доступные для некрупного бизнеса сроки и затраты, не жертвуя качеством и поддерживаемостью.
Именно такие задачи пытаются решить разработчики фреймворка Джеймикс. Имея в основе архитектуру веб-приложений Spring Boot, он за счет использования фронтенда на основе компонентов Vaadin, позволяет разрабатывать бизнес-приложения с фокусом на решение прикладных задач и без переизобретения архитектур. Разработку можно вести в контексте только одного языка программирования Java, что, впрочем, достигается не изобретением собственных блобов а выстраивается поверх стандартных технологий: HTML5, CSS, Web Components, что позволяет интегрировать сторонние фронтенд-технологии, кастомизировать существующие разработки под любые особенности Технических Заданий и развивать свои доработки в русле развития возможностей и стандартов браузеров и серверов.

Вступайте в русскоязычное сообщество Jmix разработчиков в Telegram и узнавайте, что мы создаем для корпоративной цифровизации на Jmix.