Дисклеймер

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

Откуда есть пошли SPA

Как известно, изначальной задачей JavaScript было обеспечение интерактивности на HTML-странице, и предназначался язык, в первую очередь, для верстальщиков и дизайнеров, а для программистов предлагалось использовать интегрируемые в страницу Java-апплеты. И, несмотря на сходство в названии с Java, общего у JS с нею было только оно да C-подобный синтаксис. Под капотом же JavaScript был значительно вдохновлен языком Scheme, но именно этому странному языку, написанному в кратчайшие сроки, суждено было стать одним из самых популярных на планете, и решать задачи, для которых он никогда не проектировался.

Страх и отвращение в мире JS

Первое свое SPA-приложение (сейчас такое неспешно пилится за вечерок) я написал в 2009 году, вдохновившись GMail. Вся эта магия AJAX тогда просто будоражила воображение, рисовала картины будущего, где веб-версия офисного пакета станет чем-то обыденным, даже Photoshop обзаведется ею, в DOOM 3 можно будет поиграть прямо в окне браузера с приличной частотой кадров, а десктопные приложения вообще будут летать, ведь там не нужно будет использовать медленный интерпретируемый JS... Мне тогда очень повезло, что поблизости был человек, умеющий в дизайн, и понимающий особенности верстки тогдашних сайтов. То был сайт-галерея, где снимки подгружались динамически во время пролистывания, и их можно было комментировать, вводя капчу, генерируемую PHP-скриптом. И все это без единого перехода между страницами! (Восклицание было уместным на тот момент, но сейчас вызывает, скорее, легкую ухмылку.) Тогда из фреймворков у меня был JavaScript/JScript и еще классы... ну как классы, что-то в этом роде:

function MyClass(arg1, arg2, arg3, arg4) {
	var privateProp1;
	var privateProp2;

	this.method = function(arg) {
		return privateProp1 == privateProp2;
	};

	// constructor
	privateProp1 = arg1;
	privateProp2 = arg2;
	this.publicProp = arg3;
	this._protectedProp = arg4;

	return this;
}

Кто-то будет ругаться, что методы нужно указывать через MyClass.proptype.method = ..., но, признаюсь честно, уже давно в таком стиле не писал, и как оно точно было в ту пору — уже не помню.

Конечно, уже существовала jQuery, но я всегда ее недолюбливал и считал избыточной, ведь эта маленькая библиотечка тогда нехило так добавляла к весу приложения, а использовать надо было от силы процентов десять от всего функционала, что вполне можно было реализовать прямыми руками на чистом JavaScript. Кто-то начнет тыкать в меня палкой, припоминая Ext JS, Prototype, GWT (Google Gears), и что-нибудь еще, про них могу сказать лишь то, что они, как неандертальцы, оставив в современных JS-фреймворках часть своего генома, все же оказались тупиковой ветвью эволюции.

Время шло, JS развивался, а я отошел от веб-разработки, правда, как оказалось — не навсегда.

Попытки систематизировать хаос

Интернет не стоял на месте — перед разработчиками сайтов и веб-приложений ставились все более и более масштабные задачи: сайты все больше становились похожими на своих десктопных собратьев и требовали применения иных подходов к разработке. Уже в 2010 свет увидели SproutCore от Apple (на базе которого уже через год появится Ember.js) и Angular.js от Google. Несмотря на все различия в реализации, в том числе в подходах к шаблонизации, синтаксисе и системах сборки, оба фреймворка решали одну и ту же задачу: предоставить разработчикам масштабируемый каркас для разработки веб-приложений, да и, что уж тут скрывать — оба реализовывали паттерн MVC. И правда, если взглянуть на синтаксис того же Angular.js, становится понятно, что писать на нем что-то небольшое не имело смысла — слишком велик был оверхед, хотя, признаюсь, сама идея реактивности тогда завораживала.

Как уже сказано выше, в 2011 году вышла первая версия Ember.js, который развивал идеи своего прародителя и предлагал all-in-one фреймворк, включая в себя полноценные представления в виде шаблонов на основе Handlebars и утилиты для управления проектом для создания новых элементов, запуска, сборки и тестирования проекта. Даже jQuery был на долгие годы внедрен внутрь Ember.js.)

Главным плюсом этих фреймворков была и является заранее заданная структура проекта, предусматривающая определенный подход к разработке, написанию расширений, сервисов и так далее. Жесткая структура насильно помещает разработчика в рамки заданной архитектуры фреймворка, систематизируя сам процесс разработки. Обратной стороной медали является достаточно высокий порог вхождения, спровоцированный необходимостью понимания применяемых в каркасе паттернов и методологий, а также наличием большого количества шаблонного кода, например, для описания мета-данных или дополнительных уровней абстракции. Получилось так, что отлично решались задачи энтерпрайз разработки, но для более скромных команд и бюджетов внедрение подобных технологий было слишком дорогим и трудоемким удовольствием. Специалистов на рынке с подобным количеством знаний было не столь много, и стоили они дорого. Запрос на что-то менее строгое в плане архитектуры и более простое в освоении повис в воздухе.

Поиск золотой середины

Свято место, как известно, пусто не бывает, и уже спустя два года (в 2013 году) одна небезызвестная компания, знаменитая своей борьбой с ограничениями MySQL и написанием компилируемого аналога PHP по причине наличия фатального недостатка у оного, выкладывает в общий доступ свой внутренний продукт, как они называют его, библиотеку для создания пользовательских интерфейсов — React. Впоследствии это событие вызовет лавинообразный рост интереса к разработке SPA в частности и фронтенд разработке в целом. Все дело в том, что React не навязывал какую-либо архитектуру для приложения, не требовал знания большого количества паттернов, и вообще мог быть довольно легко последовательно освоен даже начинающими разработчиками. Теперь буквально каждый мог написать за пару часов свое реактивное приложение. Впрочем, без ложки дегтя, как всегда, не обошлось: React оказался не только внутренним продуктом, который развивается без существенной оглядки на сообщество, но и экспериментом, что доказывает и нумерация версий вплоть до 0.14.8, выпущенной в марте 2016, за которой уже последовала версия 15.0.0 (А что так можно было что ли?). Сама библиотека обросла массой расширений, сторонних и не очень, концептуальными решениями вроде Flux и скриптами для инициализации, сборки и отладки приложений. В итоге, React — это такой конструктор, из которого можно собрать что угодно, от простого сайта-визитки, до сложного приложения с кучей взаимосвязанных элементов.

Впрочем, не одним React'ом едины, и в декабре того же 2013 года выходит версия 0.6 темной лошадки Vue.js. Фреймворк, вдохновленный, по всей видимости, теми же идеями, что и React, но предоставляющий чуть больше возможностей из коробки, быстро занял свое место в пантеоне JS-фреймворков. Предоставляя практически такую же гибкость, что и React, Vue.js, тем не менее, обзавелся набором собственных официальных расширений, которые отлично интегрировались друг с другом, и лучшей, на мой взгляд, из существующих (по крайней мере, среди JS-фреймворков) документацией. Теперь начинающий разработчик мог не думать над тем — какую реализацию роутера, реактивности или глобального состояния выбрать, а это существенно экономит время. Также Vue.js никогда не стеснялся заимствовать идеи у React, перерабатывать их и встраивать в собственные решения, так появились такие вещи как Vuex и Composition API.

Безусловно, JS-фреймворков куда как больше, но остальные не столь популярны, так что оставим их за скобками.

Одурманивание через упрощение

Казалось бы, наступил рай — почти все браузеры слились в экстазе с Chromium, фреймворки есть на любой вкус и цвет, бери да пиши, что пожелаешь. Но реальность оказалась суровой: огромное количество сайтов оказалось непомерно раздутыми и неоптимизированными, да еще и, благодаря технологиям и огромному количеству фронтендеров стало модно писать на JS не только веб-приложения и сайты, но также десктопные приложения, фактически, упаковывая SPA вместе с браузером в единый бинарник. Рай не наступил, но как же так получилось? Давайте попытаемся разобраться.

Экономические причины, заставляющие разработчиков использовать JS везде, даже там, где не стоило бы — оставим за скобками. В конце-концов, все помнят почивший Atom и здравствующий Visual Studio Code. Оба на Electron'е, но Atom был славен тем, что тормозил везде и всегда, а вот VS Code умудряется вполне сносно работать даже не на самых мощных машинах, так что важен не только инструмент, но и руки, которые его держат.

Снизившийся порог вхождения в веб-разработку породил огромное количество разработчиков, которые знают, как им кажется, фреймворки, или вообще отдельный фреймворк, но при этом не знают толком JS. Отсюда мы наблюдаем в проектах операции вида .slice(x, y).filter(...).map(...), совершаемые без зазрения совести не над десятками, а над тысячами объектов. Банальные ошибки из-за непонимания того, как работают асинхронные вызовы. Уверен, что многие встречали в коде какого-нибудь молодого сотрудника на работе подобную запись:

// заполняем чем-нибудь массив
const arr = [...];

// что-то где-то происходит в коде

arr.forEach(async (item) => ...);

return arr; // возвращаем массив

Если данная запись вас не смутила, то у меня для вас плохие новости. Ну а о методе разработки через copy-paste со Stack Overflow лучше вообще промолчать. Нет, не поймите меня неправильно, я сам постоянно гуглю готовые решения, и точно также копирую их с того же Stack Overflow, разница лишь в том, что сперва пытаюсь понять и адаптировать решение, а уже потом коммитить. Низкий уровень владения, собственно, языком, во-первых, заставляет допускать ошибки, подобные приведенным выше, а во-вторых, существенно затрудняет отладку и поиск неисправностей, ведь без понимания того, как устроен конкретный фреймворк, сложно понять — что и где могло пойти не так. Впрочем, эти огрехи довольно легко лечатся опытом.

Гораздо большую проблему представляет собой та самая кажущаяся простота. Пока приложение состоит из трех-пяти компонентов и пары формочек, все отлично. Не важно, выберем мы Redux или MobX для хранения состояния. Просто берем и добавляем по мануалу Vuex/Pinia + Axios в проект и получаем глобальное хранилище и запросы к серверу. Да, есть небольшой оверхед, но по современным меркам он ни на что не влияет. Но вот проект начинает разрастаться, форм уже не две, а десять, далеко не все из них состоят лишь из пары полей. Взаимосвязь между компонентами усложняется, появляется множество параллельных запросов. В какой-то момент оказывается, что частое изменение верхних уровней состояния заметно подтормаживает на Redux, поэтому, пожалуй, попробуем что-нибудь другое, может, MobX? Отличная штука этот Vuex, тут вам и глобальное состояние, и мутации, и экшены (кстати, почему нельзя напрямую вызывать синхронные мутации, или, все-таки, можно?), и вызовы api-сервера... Мы тут решили, что бизнес-логику нужно вынести из компонентов, так как становится сложно разобраться в их структуре, теперь вся наша бизнес-логика переехала во Vuex/Redux... Проект уже давно состоит не из одной страницы, а из нескольких, и при быстром переходе с одной на другую, может возникнуть коллизия данных — более ранний запрос к серверу пришел позднее и перезаписал данные в состоянии, теперь у нас выводятся не те данные, какие должны были быть. Что такое принцип единственности истины, я же просто загружаю данные с сервера? О, круто, появился новый Composition API, будем использовать его. Стоп! А зачем нам теперь Pinia? Как и когда загружать контент на страницу при переходе? Использовать глобальный индикатор загрузки или блокировать отдельные элементы? Если вы никогда не задавались подобными вопросами — у меня вновь для вас плохие новости. И проблема тут состоит из двух факторов:

  1. Резкий скачок сложности при переходе от маленького проекта к среднему и большому. Фактически на первом шаге разрабатывается еще веб-сайт, а на втором — уже полноценный тонкий или не очень сетевой клиент, что требует совершенно других знаний, и переход этот, зачастую, происходит незаметно. Просто в какой-то момент приходит осознание, что внедрение очередной фичи обходится слишком дорого;

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

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

Глобальное состояния, Flux-архитектура и вот это вот все

Особняком стоит Flux-архитектура, которая с удивительной легкостью смузи зашла в массы. Зачем разбираться во всяких сложных паттернах по типу MVC или MVVM, если можно взять готовое решение в виде Redux/Vuex/Pinia и внедрить в проект, как это показано в тысячах статей и примеров? Чтобы понять саму проблематику, нужно взглянуть на все в историческом разрезе. Когда Facebook, а ныне — признанная экстремистской на территории РФ Meta, разрабатывала React, то у них уже был готовый сайт, с работающими и отлаженными JS-скриптами. Целью Джордана Валке, первоначального автора React, было решение внутренней проблемы: обновление ленты Facebook без перезагрузки всей страницы. То есть нужно было асинхронно получать обновленные данные ленты и рендерить их на текущей странице. Вы видите здесь бизнес-логику? Вот и я не вижу. Собственно, тут стоит отдать дань уважения разработчикам — они изначально позиционировали React как библиотеку для построения интерфейсов, а не полноценный фреймворк. По сути, у нас есть только состояние, механизм его обновления и представление, являющееся функцией от этого состояния. Вкупе все это можно назвать тонким клиентом. При таком подходе, хранение индивидуального состояния в каждом из компонентов отдельно (state/setState) и механизм его обновления становятся нетривиальными с ростом количества этих самых компонентов. И здесь нашлось решение — менеджер глобального состояния, отвечающий как за его предоставление, так и за изменение. Теперь у нас есть декларативного вида представление, состоящее из компонентов без внутреннего состояния (stateless-компонентов), и состояние, которое реагирует на события этого представления:

Диаграмма тонкого клиента на React + Redux
Диаграмма тонкого клиента на React + Redux

Именно поэтому во множестве статей предлагают выполнять запросы к серверу внутри обработчиков действий (action creators). А ваше приложение тоже отлично ложится на эту архитектуру? Не зря все та же компания придумала и реализовала GraphQL, позволяющий, по сути, получать изменения всего состояния целиком, за один запрос. Ваш сервер тоже так умеет? Теперь появилось очередное решение — React Query, который должен решить проблемы кэширования запросов (EmberData, кстати, передает привет)...

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

Куда поместить бизнес-логику?

Об этом, с примерами на Vue.js и React, поговорим во второй части.

Комментарии (99)


  1. ivankudryavtsev
    16.01.2024 18:27
    +47

    Причины говнокода во фронтенде. Мнение мимокрокодила

    Тема не раскрыта. Написали много слов, а на вопрос «почему?» ни одной внятной гипотезы не предложили.

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


    1. Ilusha
      16.01.2024 18:27
      +17

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

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

      Приведенные примеры «плохо кода» не зря имеют оговорку, про обработку большого количества данных не самым оптимальным способом (хотя это нужно проверять, потому что браузеры очень хорошо умеют в оптимизации плохого кода).

      Т.е. мы видим, что проблемы возникли при масштабировании.


      1. ivankudryavtsev
        16.01.2024 18:27

        Вообще с этим не спорю.


      1. terthon
        16.01.2024 18:27
        +11

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


        1. venanen
          16.01.2024 18:27
          +4

          Формошлепить - это действительно не такая сложная работа (хотя и очень муторная и монотонная). Тут так же, как и на беке - написать форму просто, а потом приходит тз на внешний интерфейс CRM системы на табличку на 200млн ячеек в браузере, да чтобы она быстро работала, имела кучу фишек и не висла на компьютерах с 4гиг оперативки. Вот это весьма сложная задача.
          Так же и с беком - перекладывать JSON много ума не нужно, можно за полчаса на коленке собрать REST с базой. Другой разговор - когда функционал нетривиальный, эвристики сложные, а данных очень много.


      1. irtek
        16.01.2024 18:27
        +6

        "Потому что решаемые задачи элементарны. Но в совокупности - сложны."
        Красиво сказано


    1. gmtd
      16.01.2024 18:27
      +1

      Не "почему", а "зачем". Автор там в тексте пеняет что ему никто никогда не объясняет, "зачем" это надо делать. Так он сам тоже что-то не хочет на этот вопрос отвечать


    1. Devoter Автор
      16.01.2024 18:27
      +6

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


      1. Ilusha
        16.01.2024 18:27

        недостаточная подготовка специалистов

        Это мантра. Практика показывает, что на текущий день не существует программ подготовки специалистов, которые будут обладать теоретическими знаниями middle/senior-разработчиков в определенной области. Т.е. нигде и никак не подготовить.

        умение выбрать и придерживаться архитектуры

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

        Нет известно, что будет завтра, и какие будут новые требования.

        Плюс продукт - это бизнес. Это всегда баланс между деньгами, временем и результатом


        1. Kergan88
          16.01.2024 18:27

          >Практика показывает, что на текущий день не существует программ подготовки специалистов, которые будут обладать теоретическими знаниями middle/senior-разработчиков в определенной области

          Вышка по специальности в нормальном вузе какие конкретно знания пропускает?


          1. Ilusha
            16.01.2024 18:27
            +1

            Покажите мне детально программу обучения, в которой учат делать фронт на react/vue, на vanilla, на angular. Причем не поделки, а фронт уровня современных приложений в сферах b2b/b2c.

            Покажите мне программу обучения, в которой будет рассказываться про нюансы оптимизации браузером?


  1. onets
    16.01.2024 18:27
    +4

    Больше похоже на ретроспективу.


  1. Kergan88
    16.01.2024 18:27
    +19

    Целью Джордана Валке, первоначального автора React, было решение внутренней проблемы: обновление ленты Facebook без перезагрузки всей страницы

    На самом деле, несколько не так. Реакт в принципе ни когда не был универсальным инструментом в том или ином смысле и не планировалось, что он им будет.

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

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

    При таком подходе, храние индивидуального состояния в каждом из компонентов отдельно (state/setState) и механизм его обновления становятся нетривиальными с ростом количества этих самых компонентов. И здесь нашлось решение — менеджер глобального состояния, отвечающий как за его предоставление, так и за изменение.

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

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


    1. Devoter Автор
      16.01.2024 18:27
      +1

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

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


    1. jewalky
      16.01.2024 18:27
      +5

      Ну, справедливости ради, реакт в 2024 уже мутировал до полной неузнаваемости :)

      Как минимум, от него всё больше отпилили классы и прикрутили React.FC.

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

      Ну, как бы, да, но нет.

      С одной стороны, редукс — абсолютно безумная система, подразумевающая полностью глобальное состояние с одним центральным Root State. С другой стороны, моя главная претензия к редуксу — это не глобальное состояние, а бессмысленное и беспощадное MVC даже там, где это не нужно. Особенно когда он используется в комбинации с каким-нибудь RxJS, и в итоге вы пишете, по сути, клиент-серверную архитектуру, ещё до обращения к настоящему серверу.

      Видел я вырожденный вариант этого подхода, когда локальный стейт вообще не использовался. Вспоминаю, как страшный сон. Была форма contact us, было что-то типа <textarea value={feedback} onChange={...} />, а вот любое изменение в этой форме проходило через экшн вида { type: 'FORM_CHANGE', id: 'contact-us', field: 'feedback', value: '...' }. В какой-то момент мне понадобилось в другой форме редактировать структуру из вложенных объектов с массивами, я психанул и удалил весь этот код. Поэтому, к сожалению, более конкретных примеров не будет.

      А какой-нибудь контекст, хранящий в себе вебсокет и функции для манипуляций с ним — богоугодное дело. Главное, чтобы без лишних ререндеров. `useConstCallback` и его аналоги вам в помощь, равно как и штуки типа сигналов для отслеживания изменения конкретных полей контекста, а не обновление всех-всех-всех детей при любом изменении в модели.

      Кроме вебсокетов ещё могут быть сложные UI-структуры, которые должны друг с другом взаимодействовать, типа вкладок как в VS Code (с возможностью разделения на зоны и перехода с вкладки на вкладку по кнопке открытия файла).

      В общем, уходить в крайность и делать вообще любое состояние строго локальным — не менее ересь :)


  1. rundle
    16.01.2024 18:27
    +7

    Что не так с операциями вида .slice(x, y).filter(...).map(...)?


    1. jewalky
      16.01.2024 18:27
      +5

      Я думаю, тут претензия к тому, что присутствуют лишние аллокации (т.е. создание новых массивов на каждом этапе) + итерирование с нуля (сначала filter, потом по отфильтрованным map)

      т.о. аналогично такому коду:

      const sliced = objects.slice(x, y)
      const filtered = []
      for (let i = 0; i < sliced.length; i++) {
        if (...(sliced[i])) filtered.push(sliced[i])
      }
      const mapped = []
      for (let i = 0; i < filtered.length; i++) {
        mapped.push(...(filtered[i]))
      }

      Вместо:

      const mapped = []
      for (let i = x; i < y; i++) {
        if (filterObject(objects[i])) mapped.push(mapObject(objects[i]))
      }

      Хочется сказать, что во-первых, скажите спасибо, что не так:

      objects.slice(x, y).flatMap(x => filterObject(x) ? [mapObject(x)] : [])

      Во-вторых, скажите спасибо, что не immutable.js. Кто видел, тот понял.

      А в-третьих, какая-то микро-оптимизация :)

      Как минимум в реакте обычно проблема не в том, какие операции делаются, а в том, что они делаются слишком часто.


      1. rundle
        16.01.2024 18:27
        -1

        Ну да, выглядит как микро-оптимизация. JS-еры любят такие цепочки методов как в примере. И во фронтенде мы не работаем "над тысячами объектов" как пишет автор.

        Вспоминаю спор с коллегой. Есть массив чисел от 1 до 100. Нужно получить из него массив с числами от 10 до 90. Я написал так:
        arr.filter((n) => n > 10)
        .filter((n) => n < 90);

        А коллега упорно предлагал так:
        arr.filter((n) => n > 10 && n < 90);

        Задача упрощена, условия в .filter были сложнее. Хотя сложность алгоритма в обоих случаях n.


        1. ivankudryavtsev
          16.01.2024 18:27
          +6

          Я не знаю как JS оптимизирует код и итераторы, но код вашего коллеги должен быть быстрее.


          1. Aldrog
            16.01.2024 18:27
            -2

            Я тоже не эксперт в жс, но если filter ленивый (либо интерпретатор достаточно умный, чтобы для цепочки вызовов сделать его ленивым), то оба варианта в идентичный код раскроются.


            1. mayorovp
              16.01.2024 18:27
              +5

              Но filter в js не ленивый (и его невозможно сделать ленивым с сохранением обратной совместимости).


              1. nin-jin
                16.01.2024 18:27
                -6

                1. mayorovp
                  16.01.2024 18:27

                  Разумеется если ввести свой класс, то и добавить туда можно какой угодно метод!

                  Но я-то писал про стандартный filter


                  1. nin-jin
                    16.01.2024 18:27
                    -3

                    Разумеется то, что реализуемо подключаемой библиотекой, тем более реализуемо и стандартной. Было бы желание.


                    1. mayorovp
                      16.01.2024 18:27

                      Ну да, ну да. Вперёд, покажите нам как реализовать метод filter у класса Array ленивым образом, но обратно совместимо со старой реализацией.


              1. Aldrog
                16.01.2024 18:27

                А можно пояснить, какие именно эффекты сломаются, если в цепочке вызовов а-ля .slice(x, y).filter(...).map(...) все вызовы кроме последнего подменить ленивыми реализациями?


                1. mayorovp
                  16.01.2024 18:27

                  Никаких. Проблема лишь в том, что после вызова filter совершенно не обязан идти вызов map.


                  1. Aldrog
                    16.01.2024 18:27

                    Так это чисто техническая проблема, для разработчиков движков не принципиальная.


                    1. mayorovp
                      16.01.2024 18:27

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

                      И даже в этом случае будут проблемы с чистотой функций.


                      1. Aldrog
                        16.01.2024 18:27

                        Я говорю о том, что интерпретатор-то видит, идёт следом ещё какой-то вызов или нет. Соответственно, может соптимизировать конкретно кейс цепочки вызовов, подменив реализацию ленивой. По вашим же словам, это никаких проблем не вызовет.


                      1. mayorovp
                        16.01.2024 18:27

                        Интерпретатору, чтобы так сделать, надо сначала убедиться, что метод map - родной, а не подменённый. И эту проверку надо делать перед каждым вызовом filter. Как по мне, слишком много сложностей.

                        Кроме того, это в нормальном коде ленивая фильтрация проблем не вызовет, а ведь кто-нибудь может передать в filter нечистую функцию.


                      1. Aldrog
                        16.01.2024 18:27

                        Если код через сайд-эффекты полагается на то, что сначала вызовется метод из filter для всех элементов, а только затем начнёт вызываться метод из последующего map, то да, код и правда сломается.


        1. Vladimirsencov
          16.01.2024 18:27

          На таком числе разницы не будет. Попробуй в цикле несколько тысяч раз.


      1. Source
        16.01.2024 18:27
        -1

        Ну, раз уж JS вспомнил свои функциональные корни, то стоило бы предусмотреть и lazy-режим для таких цепочек вызовов. Чтобы интерпретатор сам эту цепочку в один обычный цикл преобразовывал. Типа такого: https://habr.com/ru/articles/140362/


        1. rock
          16.01.2024 18:27

          Iterator Helpers, что работают лениво, снова будут включены по умолчанию начиная с Chrome 122. Ну и полифилы никто не отменял. А через полгодика ждем в стабильном ES.


          1. Source
            16.01.2024 18:27

            Доп.либы и полифилы - это всё понятно. Но стоило бы и напрямую в язык это добавить. Впрочем, вы пишете, что в этом году уже добавят. Так что ok)


    1. Vladimirsencov
      16.01.2024 18:27

      Очень памяти много аллоцирует. Если у тебя сотни объектов небольших, то нормально. Но если даже тысячи средних. То у тебя начинает подвисать. Из за работы gc.


  1. ArtPlotnikov
    16.01.2024 18:27
    +8

    Согласен с автором. Причина говнокода - отсутствие понимание базы. Ещё всё забыли, что страница в браузере в конце концов это просто html, js и css, но простые задачи решаются избыточно сложно, оверинженеринг. На проектах внесение минимальной правки требует несколько минут пересборки. Выполнить отладку js в панели разработчика иногда невозможно, тк код на выходе не читаемый. Забивание гвоздей микроскопом.


    1. hardtop
      16.01.2024 18:27
      +5

      Более того, не всегда и не всем нужны SPA. Всем, конечно, понравились переходы без перезагрузки. Но ведь можно использовать библиотеки, вроде barba.js

      Но сейчас устоялись практики, что фронт - это обязательно js-first. И простой интернет-магазин начинает состоять из тьмы компонентов: давайте загрузим 2 мб скриптов, чтобы показать карточку товара.

      Более того, слышал тезис, что если с бека отдаёшь html - то ты дед и всё делаешь не так. Мол, потому что на курсах фронтэдеров готовят на всяких react\vue\angular и в обычный html уже никто и не умеет.


      1. TsarS
        16.01.2024 18:27

        Подтверждаю) Сейчас вот пишу интернет-магазин, в соответствии с этой статьей , на Angular. Он уже занимает 1 мегабайт. Вместе с backend и прочими, еще засунул это в 7 сервисов на docker)


      1. ArtPlotnikov
        16.01.2024 18:27
        +1

        "потому что на курсах фронтэдеров" - вот и ответ. Низкий порог входа, масса штампованных разрабов, которые следуют моде и чему их учили. Это не только в web-разработке, но и в gameDev, в музыке.


      1. mayorovp
        16.01.2024 18:27
        +3

        Более того, слышал тезис, что если с бека отдаёшь html - то ты дед и всё делаешь не так.

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

        А без клиентских компонентов никак, банальный dropdown с нестатическим списком уже за пределами возможностей чистого html. Да и в случае статического списка родной select настолько неудобен, что каждый первый сайт его на что-нибудь заменяет.

        Что-то похожее на то что нужно пытались делать в ASP.NET Web Froms, но вышло настолько непродуманно, что этот ужас до сих пор выступает антирекламой подобному подходу.

        Пока что лучшее что я встречал из того, что способно комбинировать серверный рендер и клиентские компоненты - это jQuery (с плагином Unobtrusive AJAX). В 2024м году. И я не вижу ничего удивительного в том, что выбирая между angular, react, vue и jquery, программисты выбирают первые три пункта...


        1. ris58h
          16.01.2024 18:27
          +1

          А без клиентских компонентов никак, банальный dropdown с нестатическим списком уже за пределами возможностей чистого html.

          А что мешает отдать вместе с html ещё и js, который этот список сделает динамическим?


          1. mayorovp
            16.01.2024 18:27

            Отсутствие фреймворка, который бы помог написать этот js и связать его с загруженным html.


            1. Vladimirsencov
              16.01.2024 18:27

              А что мешает в самом html его добавить. Или скрипт со статики загрузить?


              1. mayorovp
                16.01.2024 18:27

                Отсутствие скрипта для загрузки.


            1. nin-jin
              16.01.2024 18:27
              -4

              1. mayorovp
                16.01.2024 18:27

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


                1. nin-jin
                  16.01.2024 18:27
                  -1

                  Особенно бестолково ваш вброс выглядит на фоне того, что по ссылке показывается как сделать фичу, которой нет не то что во фреймворке, а вообще в языке.


            1. k4ir05
              16.01.2024 18:27

              Что-то вроде такого? https://stimulus.hotwired.dev


              1. mayorovp
                16.01.2024 18:27

                О, на первый взгляд выглядит как то что нужно. Но надо смотреть на детали.


      1. codeforcoffee
        16.01.2024 18:27

        Забавно, что эта идея сделала круг, и теперь уже node.js BFF отдаёт рассчитанный HTML, который "наполняется" JSoм в браузере.


        1. ValentineS
          16.01.2024 18:27
          -1

          Отчасти да. На втором круге идею все таки переосмыслили. Ну и BFF всё же остаётся опцией, которую можно гибко применять в необходимых случаях.


    1. DarthVictor
      16.01.2024 18:27
      +9

      Ещё всё забыли, что страница в браузере в конце концов это просто html, js и css

      Нет. Вообще нет. Страница внутри браузера - это DOM, CSSOM, очереди тасков и микротасков и много чего ещё. А HTML - это способ сериализации этой страницы.


  1. Macropulos
    16.01.2024 18:27

    Автор слегка погорячился в отношении ExtJs (компания Sencha). Начиная с 4 версии фреймворка была внедрена концепция MVC. И стоило бы упомянуть прекрасный фреймворк webix, который по степени порога вхождения, намного лучше ExtJs.


    1. Vladimirsencov
      16.01.2024 18:27

      . До сих пор эта жуть в кошмарах снится.


      1. Macropulos
        16.01.2024 18:27

        Какая именно ?


  1. fafnur
    16.01.2024 18:27
    +2

    Жалко, что автор никак не упоминает Angular.


  1. Extremum
    16.01.2024 18:27
    +6

    Разработчики без опыта могут написать говнокод во фронтенде, ну ок. Ну и в бэкенде могут тоже, да вообще везде могут. А опытные могут и из React конфетку сделать и на ExtJS с Mootols красоту навести. Причин говнокода так и не увидел в статье.


  1. shasoftX
    16.01.2024 18:27
    +11

    Причины говнокода во фронтенде где угодно. Мнение мимокрокодила

    Причина всегда только одна - сделаем быстро, а потом, если взлетит, перепишем и оптимизируем. Но "потом" редко когда наступает.


    1. SpiderEkb
      16.01.2024 18:27
      +1

      В точку.

      Дело не в стеке и инструментарии. Дело в том, что есть желание сократить ТТМ любой ценой. В том числе и за счет качества кода и архитектуры.

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

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

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

      Что еще хуже, под все это подводится теоретическое обоснование в виде (например) того же agile (не говорю что это зло, в каких-то ситуациях это вполне допустимо, но упаси господи возводить это в ранг абсолютной истины в последней инстанции, а все остальное клеймить как ересь).


      1. Ilusha
        16.01.2024 18:27

        Agile - это всего лишь про гибкость процессов работы. Всего лишь несколько слов, о том что: мы делаем работу для заказчиков/клиентов, мы можем и должны адаптироваться, мы можем и должны пробовать новое. К разработке, к коду, agile отношения не имеет.


        1. SpiderEkb
          16.01.2024 18:27
          +1

          А теперь представьте что вы рассчитываете некую конструкцию. Она должна работать на изгиб в определенном направлении. Расчет идет исходя из этого. А потом, вдруг, в результате "гибкости процессов работы" ваша конструкция начинает работать на изгиб совершенно в другом направлении. И, если вы ее не пересчитаете заново, она у вас просто разрушится.

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


          1. Ilusha
            16.01.2024 18:27
            -1

            Вы говорите про изменение требований бизнеса, а не про agile. Напоминаю, что работники бизнеса работают на него, а не не себя.


            1. SpiderEkb
              16.01.2024 18:27

              А это все и есть в комплексе.

              1. Требования бизнеса фиксируются и согласуются в виде BRD

              2. На основе согласованного BRD разрабатывается архитектура

              3. На основе BRD и архитектуры разрабатывается FSD

              4. Разработка строго по FSD

              5. Компонентное тестирование на соответствие FSD

              6. Бизнес-тест на соответствие BRD

              7. Нагрузочное, интеграционное тестирование, техтест на прелайве

              8. Внедрение на пром

              Если заказчик после этапа 1 что-то захотел поменять - задача снимается и все возвращается на начало.

              Если заказчик захотел что-то добавить после этапа 3 - это новая задача которая ставится в очередь.

              Заказчиков такая схема тоже "строит" и дисциплинирует. Они начинают понимать что хороший результат можно получить только тогда, когда сразу на берегу сформулировать четко свои требования. Более конкретно чем "сделайте нам красиво". Обычно к нам заказчик приходит с желанием автоматизировать конкретный бизнес-процесс. Который они понимают и знают что именно они хотят получить.

              Любые споры с заказчиком упрощаются - вы BRD подписали? Подписали. Бизнес-тест провели? Провели. Результат совпадают с BRD? Совпадают. Все. Мы задачу решили.


      1. Macropulos
        16.01.2024 18:27

        Видел всякое. И просто наборы таблиц в СУБД (вот где кошмар. Их там под 5000 никак не связанных между собой, даже первичные ключи отсутствовали , а отсюда и select -ыв select... результат - тормоза) , видел и отсутствие каких-либо контрактов. Что тоже не есть хорошо.

        Резюмирую: спор о том какой фреймвок лучше это как былые споры , что лучше OS/2 или Windows. Или ,если уж совсем в старину Pascal или C...


  1. Samhuawei
    16.01.2024 18:27
    +8

    Сама идея SPA противоречит гипертексту. Прочитал статейку, хочешь вернуться к предыдущей, жмёшь Alt+назад - а хренушки. Опять таки многие ссылки таковыми не являются, жмёшь Ctrl+ссылка, а новое окно не открывается. SPA это костыль для тех кому лень писать нормальное десктопное приложение.


    1. ivankudryavtsev
      16.01.2024 18:27
      +13

      В нормальных SPA ALT+< работает


    1. flancer
      16.01.2024 18:27
      -3

      А идея SPA и не должна ничего гипертексту. Это примерно как заявить, что идея программного калькулятора противоречит гипертексту.


    1. bankir1980
      16.01.2024 18:27
      +4

      Браузеры в наше время всего лишь инструмент. Запуск wasm тоже противоречит гипертексту. Да даже js ему противоречит. Тем не менее, в браузерах это всё работает. Да, spa это замена десктопным вариантам со своими преимуществами и недостатками. Да и в десктопным вариантах говнокод возможен


      1. thelifestyle88
        16.01.2024 18:27
        -3

        PWA это замена десктопным вариантам… причем тут SPA вообще…


    1. ris58h
      16.01.2024 18:27

      Я тоже не люблю тяп-ляп сделанные SPA по озвученным вами причинам, но дело то не в том что это SPA, а в том, что тяп-ляп.


    1. Dolios
      16.01.2024 18:27
      +4

      SPA это костыль для тех кому лень писать нормальное десктопное приложение.

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


  1. Galahed
    16.01.2024 18:27
    +5

    Автор, складно баишь, но между 2010 годом и озвучиванием ajax на конференции прошло 10 лет. И это десятилетие не просто эпоха и целая жизнь, оно было значительной вехой аебразработки, в какой-то мере основополагающей.

    Но и до неё люди делали асинхронные штуки через подгрузку фреймов, скриптов и даже картинок. Были рилтаймовые приложения, чаты, игры. Не какие-то куски кода, а вполне продакшн.

    Что касается реакта, то он появился когда в мире были уже высокоуровневые веб фреймаорки типа ext-js. И первоначально между ними была пропасть. Ты сидишь и можешь сделать все, любое сложное веб приложение не уступающее аналогу на десктопе. А тебя просят реакт, который кроме как идею ничего не дает. Уже сильно позже появились компонентарные фреймворки на базе реакта, вуе, ангуляр и даже агностик.

    Так вот, не jQuery единым.

    И даже если вспоминать то время, и Ext-Js первых версий - то и до него был веб приклад, который использовался в крупных системах, тот же Лотус худо бедно из коробки представлял веб интерфейсы, а под него были напилены разные ксстомные решения типа Босс-референта и проч. 1С, . Нет и проч. Целый зоопарк был уже а то время, тем страннее были все эти хайпы и переходы между фреймворками, уже тогда была асинхронрая подгрузка данных в единый движок, без смены страниц и тем страннее выглядели крики, мол у нас тут SPA

    Но все легко объясняется влиянием информации и медиапространством. Эта налаженная махина всегда будет гнать стандарты с той стороны, а не обратно и всегда очередной всем давно известный подход будут называть очередным модным словом типа Аякс


  1. Reallamos
    16.01.2024 18:27
    +5

    Автор разбирает причины говнокода не во фронтенде, а в во фронте на Реакте. И то как то вскользь.

    Причина говнокода на Реакте, это то что он очень располагает к этому. Чтобы этого не было нужен тотальный контроль, на что ни у кого нет ни времени ни ресурсов.


    1. markelov69
      16.01.2024 18:27
      +2

      Причина говнокода на Реакте, это то что он очень располагает к этому.

      При чем тут реакт если руки не из того места растут и голова тоже? Говнокод - везде, реакт не реакт значения не имеет.

      Чтобы этого не было нужен тотальный контроль

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

      На примере реакта, если видите проект где голый реакт или в связке с redux/rtk/effector/rxjs и подобным, то это сразу приговор, т.к. ход мышления у людей выбирающих такие связки сразу ясен.


      1. achepkunov
        16.01.2024 18:27

        На примере реакта, если видите проект где голый реакт или в связке с redux/rtk/effector/rxjs и подобным

        А каким должен быть проект на React? Или он должен быть вообще не на React?


        1. markelov69
          16.01.2024 18:27
          +1

          А каким должен быть проект на React? Или он должен быть вообще не на React?

          React + MobX + CSS Modules и из принципов во главе угла KISS и YAGNI


      1. Elendiar1
        16.01.2024 18:27

        На примере реакта, если видите проект где голый реакт или в связке с redux/rtk/effector/rxjs и подобным, то это сразу приговор

        Да что опять не так то!? Мимокрокодил реакт+ртк с кодогенерацией :(


      1. DarthVictor
        16.01.2024 18:27

         голый реакт или в связке с redux/rtk/effector/rxjs

        Я бы из списка убрал redux, если проект старый и не был в активной разработке. Но оставил бы RTK, потому что на момент его появления уже были более вменяемые решения. Ещё надо в список добавить использование NextJS для проектов, где не индексируется большинство страниц.


  1. 3263927
    16.01.2024 18:27
    +3

    куда поместить бизнес логику?

    правильный ответ - в blazor


  1. gen_dalf
    16.01.2024 18:27
    +4

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


    1. gmtd
      16.01.2024 18:27

      Предлагаете отрубить руки всем компетентным программном?


  1. codeforcoffee
    16.01.2024 18:27

    Ну как в меме про "твой код говно" "да".

    Проблемы понятные, для всех кто работал во фронте вообще и в реакте в частности.

    Слишком много свободы он даёт, и архитектуру/структуру/потоки данных надо самостоятельно поддерживать. Как и прочие завязанные на человека вещи, это работает пока есть ответственный, отдохнувший человек которого не торопят (такое бывает вообще ?)

    Жду вторую статью серебряной пулей (с опаской, потому что серебряных пуль нет, как мы знаем), как эти проблемы надо в реакте/фронте решать.


    1. nin-jin
      16.01.2024 18:27
      -4

      Пули можно выплавлять из разны металлов. Было бы желание. Из серебра тоже уже давно существует.


      1. eton65
        16.01.2024 18:27
        +2

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


        1. nin-jin
          16.01.2024 18:27
          -3

          Хз, о каких пунктах вы говорите, но там на сайте полно развёрнутых статей.


      1. c_kotik
        16.01.2024 18:27
        +3

        А почему ваше серебро вязкое, коричневое и плохо пахнет?


        1. nin-jin
          16.01.2024 18:27
          -2

          Маскировка, чтобы не украли.


  1. buldo
    16.01.2024 18:27

    Странно, что angular'а указан высокий порог вхождения. Это единственный фреймворк на котором у меня вообще хоть как-то получается писать фронт.

    После многих лет wfp и бэка он выглядит простым и понятным относительно остального


  1. koreychenko
    16.01.2024 18:27
    +5

    Вот вечно фронтендщики недооценивают бэкенд. Мы тоже умеем писать говнокод, просто его никто не видит. Реально же проблемы следующие:
    1. Рост от прототипа до готового сложного продукта на той же кодовой базе. (Это не фронтенд-специфичная тема)
    2. Архитектура изначального приложения оказалась также не готова к некоторым изменениям. Ну, господа, если по дороге из парохода решено было сделать самолёт, то есть вероятность, что он не полетит.

    P.S. А если автор сравнит jQuery подход к оживлению страницы с декларативным подходом во Vue.js и попробует на jQuery сделать хотя бы простенькую формочку с зависимыми полями, валидацией и прочей прелестью и сравнит трудоёмкость, то сразу станет понятно нафига все эти вундервайли затевались.


  1. murkin-kot
    16.01.2024 18:27
    +1

    Причина одна - нетребовательные пользователи. Всё остальное - следствия, включая якобы сложность, якобы массу неумелых джунов и всё подобное.

    Следствие - безумство будет продолжаться. Похоже что вечно.


  1. Source
    16.01.2024 18:27
    +4

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


    1. SpiderEkb
      16.01.2024 18:27

      Там хуже. Поколение, которое плодит абстракции ради абстракций. Этакие программисты-концептуалисты.

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


  1. uhf
    16.01.2024 18:27
    +5

    Выражу мнение как "неандерталец":

    1) новички стремятся "вкатиться" сразу во фронт, с недостатком фундаментальных знаний и ограниченным кругозором, в итоге потом вопросы "открыть сокет это какой хук в React?"

    2) язык способствует, своим дизайном, гибкостью. Функция как тип данных, замыкания, async/await и прочее вроде бы придуманы для более простого и понятного кода, но на деле могут его сделать абсолютно нечитаемым.

    3) кто-то профайлит фронтенд на потребляемые ресурсы? Ну там CPU, память? Такое ощущение, что абсолютно никто. Тормозит сайт? Купи новый компьютер.


    1. ValentineS
      16.01.2024 18:27
      +1

      1 пункт очень актуален. После проведенных примерно 40 собесов, появилось сильное желание запрета рекламы курсов фронтенда. Это просто конвейер не думающих "разрабов".


      1. SpiderEkb
        16.01.2024 18:27

        Третий тоже актуален. И не только на фронтах. Нет времени думать, нет времени тестить, нет времени профайлить. Надо быстрее херак-херак и в продакшн.


  1. Isocruzer
    16.01.2024 18:27
    -1

    Причины всех говно... что то там не так мудрены.

    Они всегда одни и те же.

    1. Это окукливание от обратной связи. Апофеозом стали боты и имейлы для обратной связи с разработчиком принимающие почту только из белого списка.

    2. Полная, небывалая в irl безнаказанность. Когда у самолёта в полёте вырывает дверь, директор многомиллиардного Боинга со слезами на глазах просит прощения, проводится расследование, находятся и наказываются виновные. Бэкэндер же обложившись менеджерами, руководителями, автопосылающими ботами и многолистовыми оправданиями "почему не" осознанно не имеет шанса ни узнать что пошло не так, ни получить не пережёванную ласковую кашку от тестировщиков, а бодрящую обратную звязь мотивирующие другие профессии к развитию.


  1. nronnie
    16.01.2024 18:27
    +1

    Единственная причина говнокода это то, что его пишут говнокодеры.