Приветствую всех. Уже как неделю я переписываю свой проект, который был на Vue options api с использованием Quasar и перевожу его на Svelte-Sveltkit-DaisyUI. Скажу сразу, он мне очень понравился, особенно в если учитывать что Vue composition api стал больше похож на React, нежели чем на самого себя. Складывается впечатление что Svelte это то к чему должен был прийти Vue, но он пришел к реакту (ты должен был бороться...).
Итак, тот код, который я писал на вью(вуй в простонародье) 10 месяцев на свелт был написан за 9 дней, и то успел добавить дополнительные функции. Кое-что еще не реализовано, но это легкая часть, которая займет дня 3-4, не больше. Затем привязка к бэкенду и тестирование и через 2-3 недели все должно быть в целом готово. Справедливости ради стоит отметить что не все время из этих 10 месяцев было использовано на написание кода. Половина времени было потрачено на безрезультатные попытки (пытки) написать бэкенд самому. Прыгал с одной технологии на другую, но в основном пытался(пытал себя) написать на фшарп. Ничего не вышло, перешел на ноду-экспресс. Кое-что вышло, но в процессе написания понял что бэк не мое. Один бэкендер говорил что работа бэкендера это как 8 часов решать "судоку" на работе, а в остальное время решать судоку для отдыха :-). Полностью с этим согласен. Главное что вовремя осознал свою неспособность писать бэкенд, а заодно и нелюбовь решать судоку. Хотя когда был в школе любил, вероятно и бэк в то время зашел бы, но не факт. Отныне, если когда-нибудь я буду писать бэк для чего-то, то буду использовать лишь готовые вещи вроде strapi или directus.
Также стоит отметить что при переписывании у меня уже был опыт и код от проекта на вью. Но на свелт все было бы быстрее даже несмотря на это, ибо свелт имеет многие киллер фичи которые вью либо убрал, либо не имел, также краткость и лаконичность синтаксиса и обилие простого сахара.
Здесь перечислю те киллер фичи которые есть у Svelte, но которые нет Vue, либо оно неудобно.
Изменение props
Самая главная фича лично для меня это способность изменять пропсы компонента. Это то чего мне не хватало у вью и то почему я не перешел на композишн апи(не только из за того что он похож на реакт). Вью опшнс апи хоть и запрещал менять пропсы, но по ссылке объекта или массива в пропсах можно было менять его свойства и получать реактивность при изменении чего-либо. Хотя все еще нельзя изменять проспы по имени переменной во вью, это очень сильно сокрощало мой код.
Свелт дает два вида передачи пропсов и один из них, как вы догадались, позволяет изменять пропсы несмотря ни на что, будь то объект, массив, или переменная с простым типом вроде строки.
<script>
import Component from "./Component.svelte"
const name = 'John Smithf'
let count = 0;
let config = {
width: 10,
height: 20,
top: 0,
left: 0
}
</script>
<Component
bind:count
bind:config
{name}>
<!-- Component.svelte -->
<script>
export let name;//Это неизменяемый пропс
export let count, config;//Этих двоих уже можно изменить, и в родителе они тоже изменятся
let increment = () => {
count++
}
let changeConfig = () => {
//Some code
}
</script>
<h1>{name}</h1>
<button on:click={increment}>{count}</button>
Не знаю как вам, но в каждом проекте я сталкивался с необходимостью менять пропс. С вью код получался просто ужасным, нечитаемым и большим. Я боялся что этот код смогу прочитать только я, однако с легким синтаксисом свелт это уже не проблема.
Также с добавлением изменяемых пропсов теперь я могу разделять свой многотонный код на еще больше компонентов, где каждый отвечает за свое. И никакой тайпскрипт не нужен. Честно, ненавижу тайпскрипт. Согласен, в команде тайпскрипт может принести некоторую пользу, но для одиночки это приносит лишь муки и снижение скорости разработки.
UseEffect
В реакте есть чудо юзэффект. У вью тоже есть computed, но почему то именно в моем коде мне приходилось всяческий изощряться чтобы заставить его работать. Он не хотел понимать что надо делать(или просто не хотел делать). Со свелтом такого нет. И в отличие от реактовского юзэффекта здесь не нужно указывать на изменение какой переменной реагировать. Компилятор сам смотрит и анализирует.
<script>
let count = 0;
let count2 = 0;
let sqr;
$: sqr = count * count; //Реагирует когда count меняется
$: sqr = count + count2; //Этот уже реагирует когда один из двух коунтов меняется. Нет нужды указывать за каким следить
</script>
Это уменьшило мой код, который было на вью просто в разы.
Each вместо v-for :key
Есть самый главный минус свелт, воистину то что было во вью. Это способность - "киллер"-фича во вью можно передать в vFor в качестве итерируемого объект или просто число <div v-for="digit in 5" :key="digit" /> и это работало. И я удивился когда не смог сделать этого в свелт.
Ну ок. Возможно никто кроме меня и не использовал никогда эту фичу, а может и да. В любом случае можно легко заменить на Object.keys или .entries и [0,1,2,3,4,5].
{#each Object.entries as [name, value], id}
<div>{id} {name} : {value}</div>
{/each}
{#each [0,1,2,3,4,5] as value, id}
<div>{id} {value}</div>
{/each}
Так я все-таки научился чему-то у курсов Шемседдинова))) Надо будет добить)))
If-elseIf-else, await, store, events
Ну тут думаю нет нужды перечислять все это. Итак ясно что if это аналог v-if из вью. Ну а с await я еще не работал, хотя итак понятно что он делает. Буду надеяться что он также удобен как и все остальное. Стоит отметить что выделение логических элементов в отдельные тэгоподобия сделало код более читаемым, нежели чем аттрибутка у вью.
Сторы ничем от реактовского не отличаются, но синтаксис делает их использование одним удовольствием.
События во вью требовали явной передачи $event-а, но свелт передает этот параметр по умолчанию, и требует явной передачи лишь когда есть другие параметры.
<script>
let handleClick = (ev) => {
console.log(ev)
}
let handleClickWithParams = (ev, param) => {
console.log(ev, param)
}
</script>
<button on:click={handleClick}>Click</button>
<button on:click={ev=>handleClickWithParams(ev, param)}>handleClickWithParams</button>
Эмиты же событий из компонента в парент я не использовал. Поначалу из за незнания пришлось на них писать, но с осознанием всего перечисленного я просто удалил их за ненадобностью, иначе они мусорили код. Серьезно, с мощью всего перечисленного я не увидел где могу использовать их в моем коде, хотя такие задачи несомненно есть.
Special elements
В свелт есть дополнительные плюшки в виде элементов window, head, body и др., к которым из компонента можно добраться только через дом. Эти элементы позволяют менять их аттрибуты прямо из компонента или странички.
<svelte:head>
<title>Главная</title>
</svelte:head>
Хотя есть элементы, которых нет, или фич которые обещали подвести, такие как <svelte:html> для того чтобы динамический менять lang или data-theme атрибуты, как сказано здесь. Или возможность добавлять html-элементы прямо внутрь <svelte:body> элемента как просят здесь. В целом это все очень помогает.
Работа с DOM и onMount
В свелт есть основные хуки, но они не очень нужны. На вью я постоянно использовал onMount, однако в свелт код и так запускается самостоятельно и нет необходимости использовать хуки без особой надобности. OnMount может быть полезен если нужно работать с DOM. Так как SveltKit по умолчанию SSR, то мой код где я хотел обратиться к document или window сломался. Я нашел два выхода. Первое - onMount, так как он запускается только в браузере то имеет все объекты. Но я отмел этот способ за неудобностью его.
Второй способ это проверить есть ли вообще эти объекты. Но if(document), if(window) все равно вызывали ошибки. Выход был найден
<script>
import { browser } from '$app/environment';
let elem;
if(browser)elem = document.getElementById();//Some code
$: if(browser)document.querySelector('.active').style.color = 'red';
</script>
Этот способ был найден мной наиболее удобным для моих задач.
Динамическая передача переменных в css
Работая с вью мне как-то понадобилось изменить css прямо в тэге <style> компонента. Сейчас это кажется бредом, но у свелт есть и это. Хотя данная фича мне нравится, но то что мне нужно сейчас она дать мне не смогла. А нужно мне динамический менять размер страницы при печати чтобы не задавать каждый раз при изменении конфига эти параметры вручную
<style>
@media print{
@page{
size: var(--paper-format)//a3, a4, a5, landscape or portrait
}
}
</style>
Однако данный код ничего не изменил. Так что если есть такая функция в самом js, буду рад если поделитесь в комментах.
Ощущения
В целом мне все нравится. Если не учитывать одного хамоватого модератора в issues, то все гуд. Пока что прощай, Vue. Здравствуй, Svelte. Хотя если Эван на Vue 4 или 5-ом сделает все похожим на Svelte-SvelteKit, то посмотрим. Но лично мое мнение, было бы классно объединись Эван Ю и Рич Харрис над объединенным svuelte или svelvue. Хотя это может все испортить и сделать только хуже. Код проекта, к сожалению, не могу показать.
Комментарии (36)
alexshipin
04.07.2023 09:04+4Самая главная фича лично для меня это способность изменять пропсы компонента
Кто вам сказал, что менять
props
это замечательно и так нужно делать всегда? Вы не меняетеprops
для компонента, к сожалению, вы меняетеstate
, если судить по примеру, который вы привели.Не знаю как вам, но в каждом проекте я сталкивался с необходимостью менять пропс
никогда с таким, лично, не сталкивался, сколько бы проектов не было за плечами.
И никакой тайпскрипт не нужен. Честно, ненавижу тайпскрипт.
TypeScript
- не зло, которое нужноненавидеть
, но "на вкус и цвет..."В реакте есть чудо юзэффект. У вью тоже есть computed, но почему то именно в моем коде мне приходилось всяческий изощряться чтобы заставить его работать.
Как это логично, не справились вы - но вините в этом инструмент. Это звучит так, "У меня не получилось забить гвоздь, виноват молоток" :)
If-elseIf-else, await, store, events
"Смешались в кучу кони, люди..." (с) М. Лермонтов. Бородино
На пункте "Special elements" я устал читать заметку автора о том, что "молоток не забивает винты, а отвертка не закручивает гвозди"... :)))
Это дело автора, его личное мнение и личная позиция, с которой спорить не буду, но дам один маленький, ничтожный совет: "Наполните заметку полноценными примерами как во Vue, так и на Svetle, чтобы у читателей была возможность в сравнение"
Pab10
04.07.2023 09:04+8У нас в компании пытались внедрить Svelte как альтернативу React для менее скиловых разработчиков, которым лень вникать в React, его жизненный цикл и это все. По итогу оказалось что изучать новый шаблонный язык, способы объявления биндингов и вот это все ОРИГИНАЛЬНОЕ в несколько раз сложнее, чем использовать JSX с нативными функциями, а сложность приложений несоразмерно выше, чем сложность инструмента. Тоесть у непрофильных разработчиков (биоинженеров) изначально не было шансов на фронте. Мой вывод с тех пор - чем ближе к нативному инструменту - тем лучше; поэтому я выбрал React.
Angular тоже не плох, но с другой стороны. Нативного там маловато, но это классический энтерпрайз фреймворк, как .NET. И если ты нанимаешь на работу ангулярщика, ты с очень большой точностью можешь определить его скилл; стиль проекта жестко регламентируется фреймворком; винтики заменяются по щелчку пальцев; ЭНТЕРПРАЙЗ!11
Все остальное делает ставку на уменьшение количества кода и увеличение количества подкапотной магии, что кажется мне лично вредным движняком, потому что ведет большое количество начинающих разработчиков не по пути изучения языка и базовых технологий (JS, DOM, CSS) а по пути изучения свистелок и перделок.
Каждый раз, читая подобные статьи, я убеждаюсь в том, что человек пока еще не пробовал разбираться в сотнях тысяч строк чужого кода, где понятность и простота стОит куда больше чем сэкономленая строчка, прячущая магию под капотом. И именно поэтому ему кажется что вот тут это реализовано лучше, чем там. TypeScript не зло, а способ написать код так, чтобы при взгляде на него было 100% понятно что он делает, какими типами оперирует в этой конкретной строчке. Да, порог вхождения чуть выше, да генерики, но на дистанции оно окупается. Для небольших проектов сгодится любой фреймворк, но стоит ли тратить время на его изучение, когда можно взять более надежный инструмент?
Ну и да. В какой-то момент разница между фронтом и бэком начинает заключаться в том, что на фронте еще и надо сделать красиво :-D
Удачи автору в начинаниях, без этих метаний между технологиями видимо никак. Желаю, чтобы они закончились поскорее и усилия шли на реализацию задуманного, а не жонглирование фреймворками.
ionicman
Так во вью четко описано, почему менять пропсы - зло - и это реально так. Если вам нужно менять пропсы где-то - значит ваша архитектура с запахом. Для всего остального можно использовать что угодно, например event-driven, provide/inject и тд.
Computed работает абсолютно четко, если четко понимать, для чего вы хотите его сделать.
Вообще, у меня за годы работы с вью не было ни одной описанной вами проблемы, при этом у нас 3 крупных SPA с нагрузкой до 10000 пользователей.
Ну и практически все остальное, из того, что вы описали - это из разряда плохих советов.
Вы реально Vue знаете? Сколько опыта у вас в нем?
А то может дело не в Svelte и Vue, а в вас - уж извините.
laatoo
тактический вопрос, помогите советом.
есть js модель seatrip (прогулка на яхте), делаем бэк-офис чтобы можно было добавлять/убирать гостей, назначать яхты, капитанов, рисовать календарь.
есть у прогулки период времени и дата, который представлен в виде Value-Object'а (в нем - datetime начала прогулки и количество часов).
есть форма, где эту дату пользователь может менять.
есть компонент, рисующий форму ввода нового периода времени, в котором нужно отрисовать текущие.
Хочется чтобы компоненты (вроде
SeatripTimePeriodInput
) работали с value-object'ами через v-model, или prop+event.В текущем виде мы через пропс спускаем компоненту VO с текущим значением, пользователь меняет значение в инпуте , компонент создает новый VO из пользовательского ввода, поднимаем ивентом новый VO на уровень формы, там подставляем в модель, узнаем ошибку, блокируем сохранение (т.к. есть ошибка), спускаем сообщение об ошибке в компонент, компонент увидев сообщение об ошибке рендерит ее и меняет статус на invalid.
Везде в туториалах counter'ы и скалярные значения, которые легко и весело реактивятся, а с моделями (которые сильно сложнее чем get/set) и объектами никто как будто дела не имеет.
Vue заворачивает объекты в свои proxy, заставляя делать toRaw/markRaw, writable-computed, выдумывать трюки по выводу ошибок рядом с формой (если на уровне компонента данные валидны, а когда попадет выше - окажется что нет, и приходится в пропс спускать компоненту сообщение об ошибке для пользователя), следить за изменениями в форме через watch, и прочие странные вещи.
Ощущение, что мне намекают, что я делаю что-то не так, и надо на уровне формы разваливать value-object'ы на скалярные значения, чтобы ниже, на уровне компонентов каждого отдельного поля работать уже с ними. Или выкидывать из головы все DDD'шные/ООПшные вещи и учиться как-то уж сильно иначе все это делать, потому что во фронтенде какая то альтернативная линия времени.
ЧЯДНТ?
mayorovp
Судя по описанию, вы и правда что-то сильно делаете не так. Для работы реактивности нужно 1 раз обернуть модель в прокси и всюду таскать этот прокси, всяческие toRaw и watch нужны для передачи объектов за пределы области ответственности vue.
По поводу паттерна Value object из DDD — такие объекты неизменяемые, им бы Object.freeze вызывать. Когда я последний раз смотрел на vue, Object.freeze предотвращал создание проксей и прочих обёрток.
Вот что делать с многоуровневой валидацией — сказать не могу, ни разу не встречался.
ООП совершенно точно выкидывать не нужно, им, напротив, надо активно пользоваться при создании моделей.
laatoo
Ну так это то что мы и пытаемся делать, потому что работа с моделью не сводится к геттерам и сеттерам вроде
seatrip.timePeriod = reactiveVueTimePeriod
.Там выходит что-то вроде
seatrip.moveTo(seatripTimePeriod, yachtAvailabilityService, <...>, notification,)
итд итп, и реактивность тут только мешает.Не очень понятны паттерны работы во vue со своими моделями, сервисами (js кодом который вполне работоспособен отдельно от vue).
Идея в том чтобы vue занимался формочками, собирал в своих формочках доменные объекты (
entities
,valueobjects
,aggregate roots
etc), и передавал уже в чистом виде в домен, а потом собранный агрегат/сущность в репозиторий, который из доменного объекта соберет DTO и отправит на апишку. Если захотим завтра переехать с vue на другой замечательный фреймворк - берем с собой домен, и делегируем задачу "собирать доменные штуки" другому замечательному удобному инструменту.Но тут утыкаешься в то, что vue как-то сильно возражает против такого с ним обращения, и надо вот иначе как-то. Как - непонятно.
Зашивать всю доменную/бизнесовую логику прям в компоненты?
mayorovp
Если у вас ViewModel, то реактивность мешать не должна. Метод moveToDate будет вызван для прокси, что-то подсчитает, в конечном счёте выставит свойства теми самыми простыми присваиваниями — и vue благодаря проксе это увидит.
А при передаче за пределы слоя ViewModel это дело да, надо отрывать от vue. Тут помогает считать вью-модель и DTO или там доменный объект двумя совершенно разными типами, даже если TypeScript с этим не согласен. Относитесь к преобразованиям туда-сюда не как к борьбе с vue, а как к преобразованию из одного типа данных в другой.
Скажем, когда вы отправляете http запрос — вам же не придёт в голову писать
fetch({ body: JSON.stringify(this) })
? Наверняка вthis
есть куча свойств которым нефиг делать в запросе, и даже если их там нет — надо расчитывать что однажды они объявятся. Вот и с передачей объектов в доменный слой или куда-то ещё работает тот же принцип.laatoo
Ну так компонент это и есть viewModel: есть доменная модель, компонент берет из него данные и из них создает свое состояние, а когда меняем состояние в компоненте - вносим изменения в доменную модель. Это и есть viewModel: мост между view и model
Ну, я не могу использовать приватные свойства
#propertyName
, и вынужден их раскрывать, потому что в прокси не заворачивается, и таким образом вся инкапсуляция идёт по одному месту.Вижу 2 варианта дизайна:
в компоненте формы сделать реф с доменной моделью (
const seatrip = ref(seatrip.plan(...))
), разбирать модель на рефы (const seatripDate = ref(seatrip.getTimePeriod().getDate()
...), эти рефы передавать вниз инпутам (<SeatripDateInput v-model="seatripDate" />
), в компоненте формы вешатьwatch
на каждый реф (watch(seatripDate,...)
), внутриwatch
мутировать модель (сюда же обработка ошибок и обновление связанных полей) и обновлять тут же обновлять реф доменной модели (seatrip.value = newSeatrip
).попахивает.
можно вместо разбора модели на отдельные рефы все это завернуть в DTO'шку, но суть не изменится: поддерживать и трогать это будет страшно и больно
сломать инкапсуляцию в доменных моделях (заменить приватные свойства публичными), в компоненте формы сделать реф с доменной моделью (
const seatrip = ref(seatrip.plan(...))
), спускать конкретным инпутам доменную модель (<SeatripDateInput v-model="seatrip" />
), они делают с ним что считают нужным, и возвращают компоненту формы новый измененный доменный объектПервый - кривой и страшный, второй компромиссный настолько, что неприемлемый.
Выбор не очень :)
mayorovp
Компонент — это View, а ViewModel должна идти к нему отдельно.
Да, приватные свойства не работают, их специально делали так чтобы они не работали с проксями. Просто не используйте их, как-то же без них кучу лет обходились. Можно использовать TypeScript, там свои soft-private свойства есть.
Или дождитесь пока во vue сделают наконец-то модели как в mobx, через декораторы, благо новые декораторы умеют работать с приватными полями. Или сделайте аналогичную библиотеку сами, там вообще несложно.
А, да, из ваших способов правильный второй, только слова "доменная модель" надо заменить на "view model". Компоненты должны работать именно с ней, с доменной моделью при её наличии работать будет уже VM. Там даже v-model не нужен, у VM своя внутренняя мутабельность должна быть.
Если же компонент настолько простой что полноценная VM ему не нужна — передавайте ему readonly через v-model.
laatoo
Спасибо.
Подскажите где можно посмотреть примеры кода, где используется этот подход?
Может подкинете почитать чего?
mayorovp
Увы, примеры кода я вам не подкину, потому что фронтом я уже не занимаюсь, весь код остался на прошлой работе.
Что почитать — гуглите по ключевым словам MVVM и SOLID. Точнее не подскажу, я до этого всего доходил сам.
nin-jin
А что же плохого в изменении пропсов?
mayorovp
Распространённая реализация, в которой свойство является отдельной переменной, ведёт к тому что эта самая переменная получает изменения сразу из двух источников. А это нарушает правило однонаправленного потока данных и приводит к трудноустранимым багам.
Вот если изменяемое свойство биндить не как переменную, а как get/set канал (или пару из значения и события) — такой проблемы не будет. Но так мало кто умеет. React так не умеет, Angular так не умеет, Vue вроде бы умеет, Svelte снова, кажется, не умеет.
Иронично что автор считает изменение props достоинством Svelte, хотя именно Vue справляется с этой задачей лучше.
ionicman
Изменение пропсов влечет за собой изменение направления потока данных, а это, в свою очередь, приводит к очень сложнообнаруживаемым багам (например, петлям пересчета).
Если нужно что-то 2-у или n-направленное (по зименениям), нужно использовать не пропс, а что-либо другое - шину например - я про это выше писал.
nin-jin
То есть плоха реализация во Vue, а не изменение пропсов само по себе.
ionicman
А причем тут Vue? Речь про направление потока данных.
В Vue можно писать и без пропсов - если очень хочется, с использованием чего-либо другого для данных - стора, шин, прокси и т.д.
Но если хочется использовать пропсы - то лучше придерживаться однонаправленого потока данных, в каком бы фреймворке это не происходило.
nin-jin
При том, что в более других фреймворках изменение пропсов не вызывает никаких проблем.
ionicman
Еще раз - проблемы возникают не из-за фреймворка, а из-за множественных источников изменения. От фреймворка в данном случае ничего не зависит, можно и во Vue, если очень хочется, изменять пропс (через функцию, например).
Но потом отлавливать где же что установило некорректное значение, и почему появилась петля в данных будет вашим личным адом.
nin-jin
Ещё раз - в более других фреймворках никаких адов и петель при этом не возникает, а вы всегда знаете кто может установить новое валидное значение, а кто это действительно делает.
ionicman
Вы мои комментарии выше перечитайте еще раз - у меня где-то что-то написано про фреймворк? Речь про данные, а не про фреймворки - когда получится это осилить - можно будет продолжать разговор.
nin-jin
Вот так вот стараешься поделикатней очередного джуна направить в правильном направлении, а он намёков не понимает и строит из себя не весть что.
mayorovp
Зря вы игнорируете влияние фреймворков. Рассмотрим следующий компонент vue:
Шаблон тут выглядит так, как будто в нём происходит присвоение свойству… между тем, поток полностью однонаправленный.
nin-jin
Тут пример по интересней. Во Vue это через жопу, конечно, делается.
mayorovp
Что-то ваш bidi ничем не отличается от ref. Или я чего-то не заметил?
nin-jin
Вся разница в том, что Vue не пытается его разворачивать, а передаёт как есть.
Graff1406
В React тоже самое соглашение об однонаправленном потоке данных. Props are immutable—a term from computer science meaning “unchangeable”.
nin-jin
React тоже не образец грамотной архитектуры.
whoisking
В чем разница для фронта 1 юзер или 10000?
ionicman
Разница в оптимизации и сложности этого фронта.
whoisking
В оптимизации чего именно?
ionicman
В минимзации всего и вся - обращений к бэку, размера этих обращений, рендеринга, их дебаунс и объединение + универсализации компонент и фронта в целом (из-за огромной фрагментации устройств, с которых сидят пользователи) и тд.
Объяснять это в комментарии долго - это тема целых докладов на хайлоадах.
Есть огромная пропасть между приложениями на десятки пользователей и на десятки тысяч на фронте. Про бэк я вообще молчу.
whoisking
На мой взгляд там нет огромной пропасти, если мы говорим про фронт. Про сложность я вообще не очень понял, как она коррелирует с количеством юзеров. Сложность на фронте зависит от фич, от поддерживаемых клиентских устройств - да, но не от количества юзеров. В сферических условиях у вас и один юзер может юзать 10 браузеров и 20 разных разрешений экранов, но речь не про это, речь лишь про количество юзеров была. Мне просто кажется немного сомнительным использовать выражение "хайлоад" в отношении фронта. У вас всегда будет 1 юзер пользоваться результатом вашей работы. В отличие от бэка, в котором как раз эти 10 тыс юзеров придут в одном место. Да, вы можете повлиять на нагрузку проекта в целом, если на фронте кривые запросы или их огромное количество, но чаще это всё-таки проблема бэка, либо решение совместное, либо вообще решение уходит в UI/UX, чтобы разбить экран на несколько или что-то в таком духе. Решения тут больше логические, чем именно какие-то архитектурные или оптимизационные, как в случае бэка. Могу ошибаться, но куда чаще, если от количества запросов с фронта падает проект, то решать проблему как раз пойдут бэкендеры на своей стороне и очень редко фронты. На бэкенде она во-первых, точно решается, а во-вторых, там всё равно всегда необходимо быть готовым к росту нагрузки и с ростом проекта такая проблема возникает почти всегда, в отличие от фронта.