Pull to refresh
13
0

Frontend ниндзя

Send message

Без негатива, тоже проходил этот путь.

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

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

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

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

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

Если брать какие то statefull системы для аналогии, то это игры и там в очень редких случаях можно обнаружить именно слоенную архитектуру и все популярные в мире фронтенда паттерны вроде State, Rendering Cycle, Observer, Component, Dirty Flag, многие из этих паттернов популярны в разработке игр.

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

А не пробовали предложить в mobx добавить функциональность подписки на экшены, выглядит так, что там не требуется много для этого?

Интересно конечно, как можно получить выигрыш в идеальных условиях по приросту рендеринга, если в обоих случаях для рендеринга используется css?)

Все что делает sc это вставляет «динамические стили» в head в тег style.

При этом, нужно понимать, что чтобы дойти до стадии Парсинга стилей которые были добавлены на страницу. Надо скачать js, распарсить, построить ast, исполнить, прогнать полный цикл рендеринга браузера и только потом браузер начнёт парсить css. Ваши тесты игнорируют все эти шаги. При использовании чистого css, этот шаг первый)

Если вам действительно нужны динамические стили, которые меняются параметрами. Есть отличный атрибут - style. Он инкапсулирован в каждом элементе, размер 0кб и не имеет оверхеда в виде целой библиотеки)

Честно, не знаю как описать в чем заключается проблема другими словами, все описал выше и вы ведь не опровергаете мои слова, а подтверждаете их)

Проблема заключается в том, что есть всего 2 пути масштабирования этого подхода, либо добавлять каждый частный случай в Form.Item, либо для каждого частного случая делать свой Form.Item. Если частных случаев будет 100, у вас либо Form.Item будет принимать 100 параметров, либо будет 100 разных Form.Item. Либо придется использовать один из паттернов от которых пытаетесь сбежать.

P.S. Меня очень смущает работа синхронной логики через асинхронный протокол через механизм postMessage. Гугл это тоже показалось оверхедом и они написали библиотеку - https://github.com/GoogleChromeLabs/comlink

Мы говорим о разных вещах. Посмотрите на конкретный пример, компонент Checkbox принимает значение checked, а не value, что мне нужно сделать чтобы поменять название пропса для принимающего компонента. Мне необходимо использовать один из паттернов, который вы написали хок/компонент-проп, иначе говоря, то что вы пытаетесь избежать, мне все равно придется использовать)

Этот подход по сути одна из реализаций паттерна миксин, а все новое, хорошо забытое старое и примерно в 2013/2014 году весь мир JS был построен на этом паттерне, можете поискать статьи того времени почему это было плохо/хорошо и сделать выводы.

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

При таком подходе вы инкапсулируете логику внутри FormItem и это хорошо, но запрещаете ее расширять не изменяя код внутри, а это на мой взгляд плохо.

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

Например компонент Checkbox принимает не value, а checked или при взаимодействием с полем, необходимо очищать/изменять другое поле, преобразовывать текущее. Да даже обычное маскирование сделать без костылей будет сложно. Нужно будет придумывать для каждого случая обходной путь или расширения внутри общего компонента.

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

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

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

Что мне нравится в микрофронтенде, что любой аргумент который используется как достоинство, можно использовать как и недостаток)

Работал и видел несколько очень крупных проектов, от 1 до 3млн строк, прекрасно масштабировались и работали. И я честно не представляю какого масштаба был бы хаос в этих проектах будь они микрофронтовыми.

Особенно классно, когда ты где то за городом или в метро, тебе очень срочно нужна информация, а вместо этого грузится angular и вроде бы ты даже его грузил, но черт, он другой версии….

А править баги связанные с ядром микрофронтов это просто адовый труд.

Я вижу только пару причин использовать микрофронтенд:

  1. переезд на другую технологию, когда требуется итеративный переход.

  2. Экономия на ресурсах других отделов, это касается именно поставки отдельных модулей/приложений. Если мы поставляем физически одно приложение из ста, то и тестировать можно одно из ста, но с этим прекрасно справляется и микросервисный монолит.

Технологию настолько наводящую хаос в проекте не встречал со времён редакса)

Холивар опен)

Мне кажется или статья специально написана так, чтобы у всех бомбануло?)

Я бы ещё добавил, что это все эксперименты и не production ready.

Интересно как подход реакта расплывается на всех платформы где хоть как то задействован UI.

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

Если коротко, без явного использования memo, вы замедляете приложение.

Ну если уже холиварить, то использование memo/useCallback в компонентах которые практически являются листьями virtual dom, это явно преждевременная оптимизация. Вы подумайте, возможно core team реакта специально не описывает это в документации, возможно создание и сверка virtual dom это операция сопоставимая с сравнением deps в useCallback/memo или вы считаете что это масонский заговор, чтобы замедлить все приложения?)
Согласен и по моим наблюдениям грамотное обоснование могут делать 1 из 10 руководителей/лидов.

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


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


Все это хорошо коррелирует позже, как правило количество незакрытых проектов прямопропорционально увеличивающимся затратам)

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

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

Так же интересно сколько обходиться поддержка такой архитектуры(написание кода/ревью кода/подбор людей/обучение и тд)?

Интересно не обойдется ли обслуживание этой архитектуры равносильно экономии при переходе на другой фреймворк.

К слову у меня был опыт перевода проекта с одного фреймворка на другой, проект не сильно крупный, около 150к строк кода, переход с vue на react, но при этом не могу сказать, что возникли крупные проблемы или у бизнеса на это были крупные затраты или задержка ttm. Думаю, что пока в целом на фронтенде преобладают компонентные фреймворки в этом нет проблемы, все сводится к переименованию методов/атрибутов/структуры файлов и тд, но честно не могу представить как ваш подход поможет при переходе например на backbone)

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

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

Есть такой кейс, у нас какое то сложное отображение UI. Например Dropdown с возможностью выбора нескольких элементов из списка. Куда необходимо положить состояние, которое будет означать открытость/закрытость элемента, список выбранных элементов и можно еще что то придумать?

А подскажите, каким образом в wpf(я не мастер этой технологии) или в идеологии mvvm, реализовать следующий алгоритм взаимодействия с интерфейсом.


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


Кто должен завершить запрос и где?

Вот что мне не нравится в архитектурах n-layer/onion/MVC и тд, так это то, что они созданы для других целей, а их пытаются применять везде. Это ведь все клиент-серверные архитектуры, где UI является всего лишь частью, они не являются рекурсивными(один блок внутри не может состоять из всей архитектуры).

Чаще всего они stateless и поток данных у них прямой, на фронтенде все работает асинхронно и самое главное у нас есть СОСТОЯНИЕ. Использование данных архитектур приводит к тому, что проект становиться невероятно сложен для своих размеров, не говоря уже о том, что крупный пример UI проекта НЕВОЗМОЖЕН на такой архитектуре.

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

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

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


Если затраты на начальном этапе больше и на этапе поддержки больше, какую пользу приносит эта архитектура?


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


Мне показалось, что вы пытаетесь создать Redux в своей архитектуре или другой state manager, просто без привязки к оным.

1

Information

Rating
Does not participate
Registered
Activity