Комментарии 77
Типичные их проблемы: не умение отсекать эквивалентные изменения и пересчёт состояний, которые никому уже не интересны.
А зачем это нужно в реальном приложении, если итоговая скорость примерно такая же?
Вы пишете:
Однако, мы можем дать приблизительную оценку вида "с таким-то менеджером состояний ваш проект будет замедляться сильнее по мере роста проекта, и вот почему".
Вы уверены, что сможете подобрать +- реальное приложение где это будет заметно? То есть как какое-то теоретическое изыскание это может быть интересно. Как тест для пулл реквеста в уже работающую библиотеку - возможно. Но на выбор библиотеки это влияеть не будет.
Борьба с ререндерами Реакта уже стала мемом, а вы до си пор делаете вид, будто проблемы не существует.
![](https://habrastorage.org/getpro/habr/upload_files/a29/f72/218/a29f722187acec2d5f9582d23d7a7e04.jpg)
Борьба с ререндерами Реакта уже стала мемом, а вы до си пор делаете вид, будто проблемы не существует.
Этой "проблемы" не существует как минимум с 2016 года в связке с MobX конечно же. Так что для адекватных людей эта "проблема" не актуальна в принципе.
И как он спасает от ререндера всего компонента для обновления одного элемента?
И как он спасает от ререндера всего компонента для обновления одного элемента?
Вот - https://codesandbox.io/s/compassionate-darwin-rsivuy?file=/src/App.tsx
И как он спасает от ререндера всего компонента для обновления одного элемента?
А, пардон, не то подумал, вы имеете ввиду обновить точечно например div из компонента при этом не вызывая рендер этого компонента да? Если да, то никак. Но это опять же вообще не проблема т.к. это супер быстро, тем более компоненты обычно разбиты на более мелкие и не являются тяжелым и монструозными
Ну вот, к примеру, компонент "Observer" помогает разбивать сложные компоненты на части без создания именованных компонентов.
А вообще, вы же сравниваете тут менеджеры состояния, а не вью-фреймворки. Вы знаете какой-то способ избавиться от полного рендера компонента силами менеджера состояния не разбивая этот компонент на части?
![](https://habrastorage.org/getpro/habr/upload_files/4b4/1ea/f82/4b41eaf82b68b9d6118e041bee0a4aec.jpg)
У мобыкса тоже проблем хватает https://www.reatom.dev/#why-not-x
У мобыкса тоже проблем хватает https://www.reatom.dev/#why-not-x
Я ни одной проблемы не увидел, кроме выдуманных и не имеющих отношения к реальности и не к джунам.
А какие реальные проблемы, например, есть?
Возможно даже в виде статьи, с вашим опытом – почему бы и нет.
А какие реальные проблемы, например, есть?
В том то и дело, что реальных проблем нет. Есть проблема в конкретных людях из-за их уровня и навыков разработки. MobX тут не причем, просто эти люди теряются и не понимают что и как делать, когда у них развязаны руки. Вот и выдумывают "проблемы" в качестве оправдания для своих слабых навыков написания нормального кода. Ведь так легко сказать, что это инструмент Х говно, а не я неумеха))
Я вижу следующе проблемы у MobX:
Сомнительное поведение по умолчанию (синхронное выполнение реакций, тривиальный компаратор), требующее глобального конфигурирования, чтобы не плодить копипасту.
Глобальный конфиг, затрудняющий интеграцию библиотек, рассчитанных на разное дефолтное поведение.
Крайне медленная инициализация и высокое потребление памяти.
Раздутый API.
Меня не один из этих пунктов не беспокоит и никак не влияет на проекты из реальной жизни. Просто модифицируешь переменные и всё работает. Экономия наносекунд и нескольких Kb/Mb памяти, в каких-то кейсах лишний рендер меня так же не волнует, ибо это вообще ни на что не влияет.
А вообще можно быстренько написать свой аналог, благо getters/setters это легко.
Проблемы не перестают таковыми быть только потому, что лично вы предпочитаете их не замечать. Мне вот интересно, что вас так сильно мотивирует заниматься евангелизмом MobX?
Проблемы не перестают таковыми быть только потому, что лично вы предпочитаете их не замечать.
Проблемы являются реальными, когда они реально оказывают негативное воздействие, которое прямо видно и ощущается невооруженным взглядом. Радиация это вредно? Да. Но уровень фоновой радиации не на столько большой, чтобы мы прям ощутимо от этого страдали. Поэтому это как бы проблема, но на самом деле нет.
Мне вот интересно, что вас так сильно мотивирует заниматься евангелизмом MobX?
Просто не люблю когда попадется проект, а там не код, а шматок говна, так ещё и такой, что даже костыли в него сложно вставить чтобы не сломать остальной функционал. Redux и прочее схожее гуано просто всячески поощеряет лютый говнокод, а MobX дает полную свободу, т.к. всё что нужно это просто мутировать переменные и всё, приложение будет само автоматически на это реагировать.
Нестабильное поведение при вызове экшенов в компутедах.
Зачем вообще вызывать экшен в компутеде?
Отсутствие поддержки SuspenseAPI.
А что именно там полагается поддерживать со стороны mobx? Выкинуть промис можно и сейчас, ловить его всё равно будет React.
По вашей ссылке мне в обсуждении накидали каких-то примеров, которые я так и не понял что должны были делать.
Зачем вообще вызывать экшен в компутеде?
Есть много причин сделать это как явно, так и случайно. Проблема именно в нестабильности поведения. И как на зло эта нестабильность может проявиться именно у пользователя.
А что именно там полагается поддерживать со стороны mobx?
Подписываться на пойманный промис автоматически и обновлять компутед по его финализации.
Это не поможет совершать из компутедов асихронные запросы, поскольку новое вычисление компутеда будет означать новый запрос, который снова выкинет новый промис.
Следовательно, эта штука может пригодиться только если вызываемый код имеет своё внутреннее состояние. Например, для связи с другой системой реактивности. Но в таком случае есть куда более лучшие способы связи чем использование Suspense.
Наконец-то я дожил до того момента, когда в мире появилось что-то идеальное!
Увы, в такое верится с трудом.
class State {
counter = 1;
constructor() {
makeAutoObservable(this);
}
}
const state = new State();
setInterval(() => { state.counter++; }, 1000);
const Component = observer(() => {
return <div>counter value: {state.counter}</div>
});
Причем тут идеалы? Ты просто пишешь код и бизнес логику без всяких убогих конструкций, обязательной иммутабильности и т.д. и т.п. и это работает четко и стабильно. Всё. Что ещё нужно для тог что делать отличные Front-end приложения?
Нет минусов = идеал. Вроде такая логика.
> Что ещё нужно для тог что делать отличные Front-end приложения?
В том-то и дело – я не знаю :)
Но хочу узнать и найти себе на будущее инструмент!
Я не фронтэндер: у меня нет рабочего опыта в разработке фронта. Только мелкие поделки ради интереса.
Но, проводя параллель с бэкэндом – если это валидно – там инструментов* без минусов не существует.
*разве что если речь про инструменты с прям уж совсем простым функционалом.
Но, со стороны, стейт-менеджеры на фронте вроде не попадают в эту категорию. Иначе за все эти годы я бы не видел тонны их обсуждений.
Аргумент с кривыми руками хоть и радикальный, но работает, это да. Правда далеко не все с кривыми руками и пустыми головами – иначе все было бы проще и кроме mobX на рынке ничего б и не было.
В общем-то я верю, что у комплексного инструмента может быть мало недостатков по сравнению с другими. Но чтоб прям вообще не было...
Поэтому я и хочу знать потенциальные минусы, ибо про плюсы всегда можно почитать на оф сайте)
Ваш пример - неструктурированная лапша, содержит утечки памяти и деградирует по перфу со временем. Сравните с кодом, лишённым этих недостатков:
$my_counter $mol_view
sub /
\counter value:
<= count? 0
export class $my_counter extends $.$my_counter {
@mem auto() {
this.$.$mol_state_time.now( 1000 )
this.count( this.count() + 1 )
}
}
Чего?! Это где вообще в том примере утечки памяти-то?
Тяжелый случай.
Можно долго и нудно ругать 3х китов индустрии и обмазываться бенчмарками.... Но факт в том, что в основе их топовости лежит доступность и стабильность для конечного пользователя не зависимости от платформы (а тут стоит припомнить предложение ТС пользователям мака самим тестить его вундервафлю).
Будет ли данная вундервафля быстрой - да бог с вами, соглашусь. Будет ли стабильной и доступной... а вот тут большой большой вопрос. И зачем мне отрезать часть аудитории при разработке проекта ради неуловимых наносекунд? Во тут и выходит - ради невнятного профита автор сам дурит бизнес и тешит свой перфекционизм.
А что насчет recoil? Его, кажется, нет в списке.
Отличное сравнение. Не совсем, правда, понятно, что с ним делать теперь. Про MobX и Redux+Reselect не знает сейчас, наверное, только ленивый, эти библиотеки широко применяются, по ним тонны документации, куча батареек и написанные интеграции с тем же React - бери и делай проект. А теперь взглянем на документацию того же $mol_wire. Там плакать хочется. Что с этим делать? Как это ввести в проект на том же реакте без боли и самописных велосипедов, дабы потом эти велосипеды не поддерживать самостоятельно? Я вот лично не понимаю какой для меня бенефит вкорячивать этот менеджер состояний в проект, в котором работают ещё и другие люди, которые в этой куцей документации разбираться точно не станут.
Ответы на ваши вопросы есть в документации.
>> Можете доработать этот пример и оформить в виде библиотеки, если готовы заниматься его поддержкой. Или реализовать подобную интеграцию для любого другого фреймворка. А мы пока отстыковываем первую ступень и летим ещё выше..
Спасибо, но нет. Я лучше воспользуюсь готовыми протестированными и рабочими библиотеками, которые всем известны, а не буду убивать всё своё время на поддержку велосипеда.
Вы правы, думаю в этом биндинге к Реакту слишком много багов:
export abstract class Component<
P = { id: string },
S = {},
SS = any
> extends React.Component<
Partial<P> & { id: string },
S,
SS
> {
// every component should have guid
id!: string
// override fields by props to configure
constructor( props: P & { id: string } ) {
Object.assign( super( props ), props )
}
// compose inner components as vdom
abstract compose(): any
// memoized render which notify react on recalc
@mem render() {
Promise.resolve().then( () => this.forceUpdate() )
return this.compose()
}
}
Сарказм оставьте при себе, пожалуйста. Зачем вы мне привели какой-то кусок кода? Какой-то Component? У меня в проекте с MobX нет никаких абстрактных классов Component, у меня чистые функциональные компоненты, мне не нужны ваши абстрактные классы. Вы, почему-то, до сих пор не можете понять что не так с вашими решениями.
У меня в проекте с MobX.. чистые функциональные компоненты
Это либо наглая ложь, либо беспросветная глупость. К счастью, я слишком плохо с вами знаком, чтобы сказать наверняка. Но на всякий случай оставлю ссылку: https://ru.wikipedia.org/wiki/Чистота_функции
Неудивительно, что у вас проблемы (которые вы сами признавали), с такой-то токсичностью. Разумеется, компоненты обернуты в observer. Что не мешает им самим без этой обертки оставаться чистыми функциями. Дело-то не в этом, в общем-то. В чём тут дело я уже написал, но вы упорно не желаете это видеть, а вместо этого кидаетесь каким-то своими кусками кода. У вас интересные и смелые идеи (с тем же Suspense API), но с таким подходом и таким отношением к людям вы далеко не уедете. Всего хорошего.
У меня-то нет проблем. Это вам приходится к "протестированному и рабочему" Реакту какие-то костыли сбоку прикручивать, чтобы он не тормозил. Что не удивительно, раз даже пару параграфов из Википедии не осилили.
>> Здравствуйте, меня зовут Дмитрий Карловский и я… крайне плох в построение социальных связей, но чуть менее плох в построении программных.
Ну да, ну да :)
И кстати, реакт в моем проекте как-то не тормозит. По крайней мере никто не жаловался, клиенты довольны. Что ещё нужно?
В данном случае это ваше незнание терминологии. Чистым функциональным компонентом называется конструкция, являющаяся одновременно чистым компонентом и функциональным компонентом. От неё никто не требует быть ещё и чистой функцией.
PureComponent - это имя класса в React. Не смотря на название, никакого отношения ни к чистоте, ни к компонентам он не имеет. К функциям тем более.
Вы правы, думаю в этом биндинге к Реакту слишком много багов
Ага, и вот вам первый: при изменении props или даже state компонент более не обновляется.
Это не баг, а фича. И в статье объясняется, зачем сделано именно так.
Ага, "объясняется". Точнее, упоминается что это сделано ради колбеков, а данные через свойства не передаются.
Так вот, я читаю это как "биндинг не поддерживает передачу данных через свойства". На этом рассмотрение биндинга можно заканчивать...
PS вы же в курсе, что в ваших статьях не работает поиск? Когда почините уже?
React + Mobx + TypeScript = Love
![](https://habrastorage.org/getpro/habr/upload_files/dcd/a90/86d/dcda9086dca0027885fbc83d8ed78b30.png)
![](https://habrastorage.org/getpro/habr/upload_files/d28/ac0/5e1/d28ac05e1f49b3f6a1eda84b81cea859.png)
У меня на m1 и телефоне за 200 баксов реатом быстрее мобыкса ?
Каждый автор СТМ пишет свои бенчи и именно его библиотека в них всегда выигрывает. А запускать миллионы апдейтов в бенчах и кричать, что там кто-то самый медленный это лицемерие.
Тот же effector, который самый медленный, спокойно может рендерить в canvas в 60fps и выше. Что опять же доказывает, что бенчи тупо не показательны. А это все попытка хайпожорить.
Другой момент — удобство разработки. Тот же MobX оказывается довольно удобен на практике и не очень важно сколько он весит и как долго запускается приложение при старте. Но вот будет ли кто-то писать на $mol или Reatom, когда у них около нуля документации, столько же реальных пользователей и сообщества, и это я еще не пишу про синтаксис. Достаточно открыть примеры кода на $mol, чтобы убедиться, что кто-то в здравом уме не будет это использовать.
Сообщество frontend разработчиков придумывает десятки способов изоляции кода, потому что иначе поддержка в большой команде это адский ад, но господин Карловский считает, что весь мир — это идиоты, и надо позволять переопределять КАЖДЫЙ кусочек любого компонента, чтобы в дальнейшем компонент не подлежал дальнейшей разработке. И конечно же отказаться от любого вида модульности в JavaScript (CommonJS, ESModules). Все должны использовать глобальные имена в модулях, ведь импорт нужного имени в локальный скоуп модуля это гораздо сложнее, чем писать каждый раз при использовании полный путь вида $mol_plot_ruler_vert.
Прежде чем принимать на веру хоть слово из этой статьи рекомендую изучить "ауру" которая сложилась вокруг автора и результатов его трудов. Как пример, нужно обязательно переопределить base64 encode, но не написать реализацию. https://github.com/hyoo-ru/mam_mol/blob/d190555a186c4936a43d914864c5e58850ca0e92/base64/encode/encode.ts
Вот референс https://mol.hyoo.ru/
А еще, не стоит оценивать бенчмарки по красивым картиночкам и результатам, которые сам автор интерпретирует как ему удобно. Я вижу, что бенчмаркинг это сложнейшая сфера, в которой очень много особенностей, которые нельзя просто так замерить через прогон пару сотен раз и вычисление среднего времени этих прогонов. Именно поэтому я не пишу бенчмарки, скорее всего я сделаю их не правильно и буду обманывать читателя.
Если интересно, почему я пишу этот комментарий, то это потому, что автор пытается замерять одну часть в каждом СТМ и в effector. Но вот незадача в том, что effector это НЕ стейт-менеджер, это штука гораздо более полная. В сообществе его называют data flow manager, и СТМ это лишь часть его. К счастью, инструменты выбирают не только из-за скорости, а еще и благодаря DX, благодаря качественной реализации которого, мы можем получить длительную поддержку проектов.
Назвать Preact, SolidJS и effector стейт-менеджерами это конечно очень смешно.
Никакой из инструментов перечисленных выше не пытается быть серебрянной пулей. Все решают определенный скоуп задач для определенной аудитории. А ставить в один ряд очень разные инструменты это конечно бред.
Предлагаю снова думать своей головой. Спасибо, за прочтение!
Достаточно открыть примеры кода на $mol, чтобы убедиться, что кто-то в здравом уме не будет это использовать.
Ну, спасибо (
надо позволять переопределять КАЖДЫЙ кусочек любого компонента, чтобы в дальнейшем компонент не подлежал дальнейшей разработке. И конечно же отказаться от любого вида модульности в JavaScript (CommonJS, ESModules). Все должны использовать глобальные имена в модулях, ведь импорт нужного имени в локальный скоуп модуля это гораздо сложнее, чем писать каждый раз при использовании полный путь вида $mol_plot_ruler_vert.
Как пример, нужно обязательно переопределить base64 encode, но не написать реализацию. https://github.com/hyoo-ru/mam_mol/blob/d190555a186c4936a43d914864c5e58850ca0e92/base64/encode/encode.ts
Эти утверждения ложные. Без базового понимания МАМ/$mol, тут не понятно что к чему.
base64 encode там не переопределяется, это пользовательская функция. Тут можете подробнее разобраться в МАМ, так получится дать более качественную обратную связь/критику.
С документацией есть проблемы, да.
Прежде чем принимать на веру хоть слово из этой статьи
А еще, не стоит оценивать бенчмарки по красивым картиночкам и результатам, которые сам автор интерпретирует как ему удобно.
Зачем принимать слова на веру из этой статьи? Методика измерений описана, можно самостоятельно оценить, если она ошибочна можно предложить исправления/дополнения или свою, или ничего не делать
рекомендую изучить "ауру" которая сложилась вокруг автора и результатов его трудов.
Ага, надо читать и пользоваться трудами только от популярных авторов
Если интересно, почему я пишу этот комментарий, то это потому, что автор пытается замерять одну часть в каждом СТМ и в effector.
Выглядит так, что вы оскорблены тем, что эффектор на последнем месте. Чтобы это скомпенсировать, вы предлагаете взглянуть на другие части, выходящие за рамки статьи.
Другой момент — удобство разработки.
DX не тема статьи, согласен с его большой важностью. По поводу того, что бенчи мало показательны, ваша мысь понятна. А у вас есть идеи/решения как сравнить DX разных фреймворков/библиотек?
А запускать миллионы апдейтов в бенчах и кричать, что там кто-то самый медленный это лицемерие.
Методика измерений описана в статье. Ознакомьтесь с ней, чтобы не говорить глупостей.
будет ли кто-то писать на $mol ... Достаточно открыть примеры кода на $mol ... Вот референс https://mol.hyoo.ru/
А $mol тут каким боком? В $mol пространстве имён сотни ортогональных библиотек. Упомянутая в статье $mol_wire - лишь одна из них. Использовать её я никому тут не предлагал.
Как пример, нужно обязательно переопределить base64 encode, но не написать реализацию.
Реализации под ноду, браузер и тесты для них лежат рядом.
Именно поэтому я не пишу бенчмарки, скорее всего я сделаю их не правильно и буду обманывать читателя.
Вы и без бенчмарков прекрасно обманываете читателя, не приводя никаких пруфов:
![](https://habrastorage.org/getpro/habr/upload_files/c9e/2e7/b7f/c9e2e7b7f900c44bcd95cf62ec2371a4.png)
А всё потому, что Эффектор сливает во всех бенчмарках. Вот ещё пример с todomvc:
![](https://habrastorage.org/getpro/habr/upload_files/07f/000/c49/07f000c49d3eace9d69a7bf2c091db1e.png)
Назвать Preact, SolidJS и effector стейт-менеджерами это конечно очень смешно.
![](https://habrastorage.org/getpro/habr/upload_files/04d/295/e90/04d295e90a467516cc84e29c131762f2.png)
![](https://habrastorage.org/getpro/habr/upload_files/b5b/439/75e/b5b43975ec70dcbc6581402a0ef99e43.png)
effector это НЕ стейт-менеджер, это штука гораздо более полная. В сообществе его называют data flow manager, и СТМ это лишь часть его.
Вывеску поменять забыли:
![](https://habrastorage.org/getpro/habr/upload_files/869/a76/17f/869a7617f5f0b459f33a296b68174607.png)
Но совершенно не важно, что как называть. Все библиотеки тестировались в одинаковых условиях на одинаковых задачах.
Добавьте Zustand к сравнению
Меня вот статьи Дмитрия заставляют сначала пойти почитать комменты, как его там хейтят, а потом - задуматься. Как с лауреатами игнобелевской премии - вроде делают что-то смешное, несерьезное, получают какие-то ненужные результаты, а потом оказывается, что и работа, и результаты, хоть на первый взгляд и выглядят как-то легкомысленно, несерьезно и смешно, а на самом деле дают очень даже серьезный материал для размышлений.
Здесь, как я понимаю, предлагается задуматься о штуках, которые еще не дошли даже до мэйнстрима, и только-только доходят. Исторически мэйнстримом сначала было то, что называется сейчас "системным программированием" (ассемблер и машинные коды), потом было процедурное программирование (Си и Паскаль), потом так называемое "объектно-ориентированное" в виде Java (это вот 1996+ года), потом до мэйнстрима добралась символьно-фукнциональная парадигма (в виде (Java | Type ) Script-а, который внутри лисп), и вот сейчас начинает быть понятным, что хочется еще более удобную в использовании парадигму, которая вроде бы называется "nonmonotonic dataflow programming" (http://lambda-the-ultimate.org/node/2710#comment-40546, где по сути смешиваются функциональная и декларативная), и именно ее пытаются с разной степенью пряморукости реализовать эти библиотеки, о которых идет речь - "менеджеры состояний". Именно она может в перспективе прийти то ли на смену, то ли в дополнение к символьно-функциональной. А видели мы это еще в MS Excel в далёком 1995 году, где программирование выглядит именно так: в ячейку вводишь либо ее значение ("состояние"), либо формулу, описывающую ее зависимости от окружения, и при изменении окружения вся таблица должна пересчитаться, желательно оптимальным способом. Причём Excel проектировали люди, которые об оптимизации всего чего можно думали с самого начала (там даже формат ранних xls-файлов был двоичный, и их не надо было парсить, достаточно было прочитать в память, и нужные структуры данных после этого уже сразу располагались на своих местах, поэтому оно открывалось приемлемо быстро даже на 486-х машинах). И, имхо, именно благодаря именно Excel у пакета MS Office оказался такой потенциал, задел, и запас прочности. Word явно хуже спроектирован и сделан, не говоря о Power Point и остальном, идущем в нагрузку.
Поясните мне кто-нибудь один момент. RxJs на сколько я помню, это библиотека для удобной работы со стримами - потоками данных. Да, на базе это библиотеки можно построить стейт-менеджер, но это только одно из множества возможных применений ее. А за своевременное обновление вьюхи при изменении состояния, если мне память не изменяет, отвечает Zone.js.
Или я не прав?
А подскажи как добавить мой стейт менеджер https://github.com/LabEG/reca в тест?
Получается мне нужно просто класс написать отнаследовав от автостора, со свойствами и методами и все?
Да, присылайте код - я добавлю.
Сделал копию с mol_wire_solo. Цифры не сходятся. Там как то кеш должен отработать?
// https://mobx.js.org/observable-state.html
const { AutoStore } = $mol_import.module(
'https://esm.sh/reca'
)
class App extends AutoStore {
A( next = 0 ) { return next }
B( next = 0 ) { return next }
C() { return this.A()%2 + this.B()%2 }
D() { return numbers.map( i => ({ x: i + this.A()%2 - this.B()%2 }) ) }
E() { return hard( this.C() + this.A() + this.D()[0].x, 'E' ) }
F() { return hard( this.D()[2].x || this.B(), 'F' ) }
G() { return this.C() + ( this.C() || this.E()%2 ) + this.D()[4].x + this.F() }
H() { res.push( hard( this.G(), 'H' ) ) }
I() { res.push( this.G() ) }
J() { res.push( hard( this.F(), 'J' ) ) }
}
const app = new App();
/*//*/ const tick = ()=> {
/*//*/ app.H(); app.I(); app.J() // $mol_wire_fiber.sync()
/*//*/ };
tick();
Добавил:
![](https://habrastorage.org/getpro/habr/upload_files/2fa/3c5/516/2fa3c5516a6dc286eb020ef88ea268d5.png)
Лишние вычисления, что приводит к низикм показателям: EFHEFFJ + EFHEFFJ
Лишние вызовы эффектов, из-за отсутствия отсечения эквивалентных значений, что и приводит к падению тестов.
Получается это не тест стейт менеджеров, а тест систем мемоизации?
В частности делается допущение что результат работы функции всегда зависит от входных параметров? Хотя в реальной жизни функция постоянно берет данные из вне, например из сетевого запроса или банальный Mtah.random() сломает всю мемоизацию?
Тогда уж тест реактивных систем на базе разных менеджеров состояний и менеджеров потоков исполнения.
Результат работы функции зависит от параметров и зависимостей. Если ни то, ни другое не поменялось, то вызывать её на всякий случай нет смысла, иначе придётся на каждый чих пересчитывать всё приложение, что будет сильно тормозить.
Big State Managers Benchmark