Pull to refresh

Comments 118

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

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

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

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

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

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

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

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

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

Но ведь так и есть! Настоящие девсы - это бэкендеры (особенно в финтехе), фронты - это просто низкоквалифицированные кадры.

Я вам больше скажу, в банковском ИТ фронт - это процентов 5% от всего софта. С соответствующим к ним отношением.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ну, начнем с начала. Тайпскрипт с его широтой и глубиной. Системы сборки. Пакетные менеджеры. Нюансы работы nodejs. Однопоточность/многопоточность в контексте работы JavaScript в разных окружениях. This. CSP. Wasm. Workers. Полифилы. Accebility. Особенности работы с dom. Работа с ресурсами (камера, звук и т.д.). DOM и Range. Паттерны работы с Proxy/Reflect. Разные архитектуры под разные типы приложений: SSR, PWA, SPA, etc. Weak-объекты. Знание и понимание того, как браузеры оптимизируют: ускорение работы, оптимизация батареи. Repaint/reflow. Метрики. Трейсиги на уровне клиентского приложения. Локализация: api браузера, стандарты индустрии. Разные полезные стандарты/RFC, которые могут быть полезными. Тесты: от unit до e2e. IndexDB. Bad Practice. OpenAPI. Выстраивание ui-kits. Работа с design tokens на уровне draft-стандарта. Packages. Паттерные применения генераторов. Стратегии code review. Стратегии рефакторинга. Browser extensions. Часто используемые библиотеки. Навыки дебажить. Кроссбраузерная работа вплоть до webview. Работа с обертками под мобильные платформы типа capacitor. Прототипное наследование. WebRTC.

Я уже не говорю про фреймворки: паттерны их организации, паттерны работы с ними. История развития: почему и зачем. История развития индустрии: от чего отказались и почему. И не прошу даже рассказать про альтернативы nodejs. И про докеры. И про ASP.NET.

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

Есть профессия: fronted-разрабочик. Но нигде ей не учат. Вузы считают, что достаточно дать общие навыки «писать код» и «ооп». Иногда еще алгоритмы дадут. А учатся начинающие промышленной разработке на первой работе.

Сделаете курс Юдэми? Обещаю, что куплю!

Зачем? Есть нафталиновая шутка: чем меньше хороших спецов, тем выше у хороших зарплата.

Вот тут мой оппонент говорит, что за 2-3 дня будет обладать вышеперечисленными знаниями. Обратитесь к нему, он явно знает какой-то секрет :)

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

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

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

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

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

Так я же задал вполне четкий вопрос, вы на него не ответили.

Ну, начнем с начала. Тайпскрипт с его широтой и глубиной. Системы сборки. Пакетные менеджеры. Нюансы работы nodejs. Однопоточность/многопоточность в контексте работы JavaScript в разных окружениях. This. CSP. Wasm. Workers. Полифилы. Accebility. Особенности работы с dom. Работа с ресурсами (камера, звук и т.д.). DOM и Range. Паттерны работы с Proxy/Reflect. Разные архитектуры под разные типы приложений: SSR, PWA, SPA, etc. Weak-объекты. Знание и понимание того, как браузеры оптимизируют: ускорение работы, оптимизация батареи. Repaint/reflow. Метрики. Трейсиги на уровне клиентского приложения. Локализация: api браузера, стандарты индустрии. Разные полезные стандарты/RFC, которые могут быть полезными. Тесты: от unit до e2e. IndexDB. Bad Practice. OpenAPI. Выстраивание ui-kits. Работа с design tokens на уровне draft-стандарта. Packages. Паттерные применения генераторов. Стратегии code review. Стратегии рефакторинга. Browser extensions. Часто используемые библиотеки. Навыки дебажить. Кроссбраузерная работа вплоть до webview. Работа с обертками под мобильные платформы типа capacitor. Прототипное наследование. WebRTC.

Просто в кашу намешали. Зачем фронту нюансы работы nodejs? На одном конкретном проекте вам понадобится едва ли треть от написанного, а со второй третью 90% фронтенд-разработчиков не встретится ни когда в жизни.

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

Ну а для уровня нинзи нужна практика - т.е. навыки, а не знания.

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

Есть профессия: fronted-разрабочик. Но нигде ей не учат. Вузы считают, что достаточно дать общие навыки «писать код» и «ооп». 

Все верно, этого достаточно.

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

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

В целом утверждение - "на фронте много говнокода" само по себе лжёт. Говнокод есть везде и всегда, и на мой взгляд на фронт ему сложнее просочиться, так как он всегда виден. То каким адом может быть код на бэке может быть не ясно вплоть до точки невозврата.
Сейчас на фронте есть куча сигналов, в которых даже простой пользователь заподозрит неладное. К примеру, "моргающий интерфейс" - сообщит о проблемах со стейтом, или когда лагают даже нажатия на кнопку можно понять, что где-то есть неоптимизированные вычисления блокирующие весь евентлуп. Таких маркеров много, их легко найти, они всегда заметны бизнесу. А вот у бекенда почти никогда нет пользователей непосредственных, по этому проблемы бекенда обычно выглядят как проблемы фронта, за редким исключением.
Так что найти говнокод на фронте намного легче.

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

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

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

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

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

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

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

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

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

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

Ну, справедливости ради, реакт в 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 (с возможностью разделения на зоны и перехода с вкладки на вкладку по кнопке открытия файла).

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

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

Я думаю, тут претензия к тому, что присутствуют лишние аллокации (т.е. создание новых массивов на каждом этапе) + итерирование с нуля (сначала 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. Кто видел, тот понял.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Эта штука позволяет делать запросы и подменять части страницы, но никак не помогает интегрировать в страницу клиентские компоненты. То есть замена для Unobstrusive AJAX. А нужна замена для JQuery и его плагинов.

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

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

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

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

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

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

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

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

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

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

В точку.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Золотой коммент.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Говнокод можно писать где угодно и на чем угодно. React, Vue и Angular не панацея всегда. Если хочется возможностей реакта, но с меньшим размером - можно взять preact. Он вполне годный. Что бы не тащить тот же Redux, можно использовать и useReducer. Его возможностей вполне хватает и будет легко делить большие SPA на асинхронные модули.

А бекенд, уж при желании, можно тоже на js писать.

Статья, имхо, заход прям очень уже не с той стороны.

Как мне кажется, "проблема говнокода" - она вообще не лежит в, скажем так, сколь-нибудь технологической плоскости.

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

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

Ну а то, что при достигнутом результате потом "главное, не трогать несущую трубу" (с) - вообще мало кого волнует. Да вообще никого, можно сказать :-)

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

Скупой платит дважды (а дурак платит всю жизнь). Кто не хочет сейчас заплатить за "абстрактный красивый код", тот будет потом бесконечно платить и переплачивать за доделки и переделки говнокода.

... тот будет потом бесконечно платить и переплачивать ...

Во-первых, "как что-то плохое" (tm) :-)
А во-вторых, что-то мы как-то не наблюдаем толпы тех, кто уже... что несколько печалит.

На данный момент, единственное, что мы - как исполнители - точно знаем: это то, что если "говнокод" и является проблемой, то это "проблема издержек". Со всеми вытекающими...

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

Когда-то писал довольно развернутые приложения на Delphi. Десятки форм с разной степенью генерации содержимого по метаданным. Grid, list, edit, label собранные на Panel или саму форму. В том числе с получением и сохранением данных во внешних источниках — невидимый DataSet и визуальные компоненты с приставкой Data. Сложность была контролируемой. Понятной. Вменяемый цикл событий. При желании, вполне можно было реализовать реактивность. В нужном объеме.

Так может проблемы WebGUI в недостаточном уровне инкапсуляции? И безальтернативной реактивностью? Слишком близко к низам — html, css. Нет вменяемой объектной модели компонентов. И только один поток связывания, где надо и не надо.

С приставкой "DB" =)

Sign up to leave a comment.

Articles