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

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

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

Методика измерения

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

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

  • Batch Changes. Должна быть возможность разом обновить несколько состояний, не перевычисляя весь граф лишний раз.

  • Order Independent. Порядок внесения изменений не должен влиять на порядок пересчёта узлов графа - он в любом случае должен выполняться в оптимальном порядке.

  • Ignore Unrelated. Порой зависимость в коде не даёт зависимость по данным. В этом случае изменение зависимости не должно приводить к пересчёту зависимого.

  • Collapse Double. Для вычисления значения узла зависимость может потребоваться несколько раз, но это не должно приводить к лишним вычислениям.

  • Skip Untouched. Если зависимость по факту никому сейчас не требуется, то и вычислять её не надо.

  • Skip Redundant. Если новое значение зависимости эквивалентно предыдущему (например, новый массив, но с теми же значениями), то зависимые состояния пересчитывать нет смысла.

  • Reuse Moved. Порядок обращения к зависимостям при вычислении может раз от раза меняться, но это не должно приводить к пересчётам этих зависимостей.

  • Single Source. Множественные подписки с побочными эффектами на одно и то же состояние, не должны приводить ко множественному вычислению этого состояния.

  • Effect Once. Какой бы сложный ни был граф состояний, на одно изменение исходных состояний, побочный эффект должен быть выполнен лишь однажды.

В коде это выглядит примерно так, если не использовать никаких реактивных мемоизаторов и шедулеров:

let A = 0 // unique values: 1 2 3 4 ...
let B = 0 // toggle values: 1 2 1 2 ...
const C = ()=> A % 2 + B % 2 // toggle values
const D = ()=> [ A % 2 - B % 2 ] // same value: [0]
const E = ()=> hard_work( C() + A + D()[0] ) // unique values
const F = ()=> hard_work( D()[0] && B ) // same value
const G = ()=> C() + ( C() || E() % 2 ) + D()[0] + F() // toggle values
const H = ()=> side_effects.push( hard_work( G() ) ) // toggle values
const I = ()=> side_effects.push( G() ) // toggle values
const J = ()=> side_effects.push( hard_work( F() ) ) // single run

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

Если формулы будут тривиальными, то самым быстрым решением окажется то, где идёт полный пересчёт всех состояний. На ультра-малых проектах (привет, Мир!) полный пересчёт может быть как быстрее, так и медленнее, но производительность менеджера состояний в них не особо и важна - так и так будет достаточно быстро. А вот по мере роста проекта лишние пересчёты будут всё сильнее замедлять приложение. И насколько сильно будет это замедление - очень даже важно.

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

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

На графе состояний можно видеть:

  • Исходное состояние A меняется на уникальное значение на каждой итерации.

  • Исходное состояние B переключается между двумя значениями на каждой итерации.

  • Промежуточное состояние C переключается между двумя значениями на каждой итерации.

  • Промежуточное состояние D на каждой итерации выдаёт массив с одними и теми же значениями внутри.

  • Промежуточное состояние E на каждой итерации то участвует в вычислениях, то не участвует. В первом случае это требует тяжёлых вычислений, а в последнем пересчитываться оно не должно.

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

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

  • Тяжёлый побочный эффект J, наоборот, исполниться должен лишь однажды, так как его зависимость не меняется.

При инициализации большинство решений исполняет все 4 тяжёлых вычисления по одному разу: EFHJ. А вот на каждой итерации могут быть более разнообразные варианты. Вот наиболее частые:

  • Оптимальный: H + EH = 3

  • Без проверки на эквивалентность: FH + EFH = 5

  • Полный ленивый пересчёт: FHFFJ + EFHEFFJ = 12

  • Пересчёт каждого пути: HEEEHFHEEHFF + HEEEHFHJHEHEHHFHJF = 30

По последнему пункту у вас может возникнуть резонный вопрос: да кто в своём уме будет такое бестолковое решение использовать? Однако, именно оно используется в одном из веб-фреймворков большой тройки. Но об этом позже..

Анализ результатов

Итак, время пришло, запускаем коллайдер:

Так, что за дела? Почему половина библиотек завалила тесты? А всё просто - они либо выдавали побочные эффекты для грязного состояния, либо выдавали их лишний раз, либо всё вместе. То есть эти библиотеки не пригодны к использованию в продакшене вообще. Прощай Vue, прощай React + Redux, прощай Angular + RxJS.

Ну ладно, допустим наш вымышленный большой серьёзный проект не нуждается в корректном поведении, а только в высокой производительности, так что отключим тесты, и снова запустим коллайдер:

Как читать градусники

  • ???? Холодный старт - нет JIT оптимизаций

  • ???? Горячий старт - JIT оптимизации возможны

  • ???? Оценка размера тестового кода (код после // игнорируется)

  • ???? min-zip объём загруженных библиотек

  • Производительность - слева, потребление памяти - справа

Классификация решений

По типу API

  • ???? Object. Состояние хранится в объектах, логика работы с ним пишется в методах.

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

  • ???? Functional. Состояние хранится в некотором контексте, а логика описывается как композиция чистых функций.

По энергичности

  • ???? Instant Reactions. Если не завернуть изменение нескольких исходных состояний в транзакцию, то обновление всех зависимых состояний и применение побочных эффектов произойдёт несколько раз синхронно для каждого изменяемого исходного состояния.

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

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

Лига выдающихся менеджеров состояний

Встречаем лидеров: $mol_wire, MobX, ReAtom, WhatsUp, CellX. Они наиболее оптимально разрулили потоки данных, что дало минимальные накладные расходы: H + EH = 3

$mol_wire

Библиотека ничего особенного не обещает в плане эффективности, однако именно она показала себя лучше всего в нашем бенчмарке. Как ей это удалось? Об этом можно почитать в статье: Проектируем идеальную систему реактивности.

MobX

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

ReAtom

Библиотека показывает отличную эффективность в нашем тестовом примере, не смотря на активное использование иммутабельности под капотом:

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

WhatsUp

Отличное решение, которое обещает нам:

..и отвечает за свои слова.

CellX

CellX, как и обещал, показал выдающиеся результаты, лучшие после $mol_wire, но запутался в порядке применения побочных эффектов, и был, надеюсь временно, за это дисквалифицирован. Но расплатой за такую скорость оказалось большое потребление памяти.

Менеджеры состояний со скамейки запасных

Библиотеки, которые звёзд с неба не хватают, но всё же проходят тесты: SolidJS, Reactively, Preact, MaverickJS, Spred, FRP-TS, Effector.

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

SolidJS

Библиотека обещает нам бесплатную производительность за счёт детальной реактивности:

А оказывается, что она не умеет эффективно отсекать нерелевантные вычисления: EH + EH = 4

Reactively

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

На деле, конечно же, чуда не произошло, из-за отсутствия планировщика и отсечения эквивалентных изменений: FH + EFH = 5

Preact

Библиотека обещает быть быстрой на любых размерах приложений:

Однако, без отсечения эквивалентных изменений этого не достичь: FH + EFH = 5

Spred

Библиотека обещает нам отсутствие лишних вычислений и отличную производительность:

Но ведёт себя странно, иногда не отсекая эквивалентные изменения и не пропуская вычисления, результат которых уже никому не нужен: EH + EFH = 5

MaverickJS

Библиотека обещает лишь базовые оптимизации:

Так что не удивительно, что максимальной эффективности она достичь не может: EFH + EFH = 6

FRP-TS

Библиотека обещает лишь избавить нас от глитчей:

И действительно с этим справляется. К сожалению, функциональная природа не позволяет ей сэкономить на вычислениях, что даёт посредственную эффективность: EFH + EFH = 6

Effector

Библиотека обещает нам максимум производительности за счёт некоей статической инициализации:

Но оказывается самой медленной из тех, кто не завалил тесты. Всё же в реальных приложениях довольно много динамики и её становится всё больше по мере роста проекта. Так что крайне важно уметь эффективно работать в рантайме, а не полагаться на ручные оптимизации потоков данных в коде. Вот и получаем: EFH + EFH = 6

Тоже своего рода менеджеры состояний

На доске позора у нас: uSignal, Vue, LegendApp, Jotai, S.js, Redux + Relect, Hydroxide, RxJS. Помимо просто лишней работы, замедляющей приложение, они так же выполняют и лишние побочные эффекты, что может быть источником множества багов.

uSignal

Библиотека грозится дать нам ультралегковесную версию реактивности из Preact и SolidJS:

Но чуда, конечно же, не произошло - анорексия сказывается на эффективности не лучшим образом: FHJ + EFHJ = 7

Vue

Фреймворк представляется нам достаточно производительным:

Тем не менее, в его основе лежит реактивная система сомнительной эффективности: FHJ + EFHJ = 7

LegendApp

Библиотека обещает нам починить React с помощью мелкозернистой реактивности, чтобы его не приходилось постоянно оптимизировать вручную:

Однако, показала она себя в два раза хуже, чем полный пересчёт графа состояний. Кажется она издевательски смеётся над нами, повторяя одни и те же вычисления несколько раз подряд: EHE + HEHE = 7

Jotai

Библиотека обещает починить React, чтобы его можно было использовать и для больших приложений:

Но показывает она почти самые худшие результаты, делая кучу лишней работы: EFHJ + FEHJ = 8

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

S.js

Библиотека обещает нам быть простой и быстрой:

Но быть эффективной на больших проектах она не обещает, так что ничего удивительного: EFHJ + EFHJ = 8

Redux + Reselect

Reselect обещает нам починить Redux, чтобы хотя бы селекторы в нём стали эффективными:

Но нам же никто не обещал максимальной эффективности, так что получаем: EFHJ + EFHJ = 8

Hydroxide

Фреймворк хвастается своей экстремальной производительностью:

Но вы только гляньте, какую дичь он творит, получая производительность меньше, чем у полного пересчёта всего графа состояний: EFEFHJHJ + EFEFHJHJ = 16

RxJS

Библиотека обещает нам улучшенную производительность относительно оригинальной библиотеки:

И показала наихудшую производительность, на порядок отстав от лидера, и в два раза от полного пересчёта. Всё дело в том, что, вместо оптимизации потоков данных, она тупо пересчитывает весь граф состояний обходя его в глубину по всем возможным путям: HEEEHFHEEHFF + HEEEHFHJHEHEHHFHJF = 30

Сухой остаток

Самые неэффективные технологии зачастую хвастаются своей максимальной производительностью. На микробенчмарках с полным пересчётом всех состояний самое тупое решение легко может показаться самым быстрым. Но эти спринтеры не способны пробежать марафон, падая на обочину уже с тривиальных тестов корректности применения побочных эффектов. Разработчики ищут ключи там, где светло (оптимизации кода), а не там, где их потеряли (оптимизации архитектуры). Для лучшего понимания ключевых проблем в реактивных архитектурах, лучше глянуть мою давнюю лекцию: Main Aspects of Reactivity

Настоящий ужас вызывает то, насколько кривые системы реактивности лежат в основе так называемой большой тройки самых популярных веб-фреймворков: React, починить который не пытался только ленивый; Angular, на полном серьёзе предлагающий использовать RxJS; Vue, дёргающий побочные эффекты по поводу и без. Как мы до этого докатились, я рассказывал недавно в выступлении: Как программисты дурят бизнес?

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

Текст статьи подготовлен в $hyoo_page.

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


  1. DarthVictor
    26.12.2022 11:26
    +1

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

    А зачем это нужно в реальном приложении, если итоговая скорость примерно такая же?


    1. nin-jin Автор
      26.12.2022 11:31

      1. DarthVictor
        26.12.2022 14:26

        Вы пишете:

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

        Вы уверены, что сможете подобрать +- реальное приложение где это будет заметно? То есть как какое-то теоретическое изыскание это может быть интересно. Как тест для пулл реквеста в уже работающую библиотеку - возможно. Но на выбор библиотеки это влияеть не будет.


        1. nin-jin Автор
          26.12.2022 14:45

          Борьба с ререндерами Реакта уже стала мемом, а вы до си пор делаете вид, будто проблемы не существует.


          1. markelov69
            26.12.2022 16:15

            Борьба с ререндерами Реакта уже стала мемом, а вы до си пор делаете вид, будто проблемы не существует.

            Этой "проблемы" не существует как минимум с 2016 года в связке с MobX конечно же. Так что для адекватных людей эта "проблема" не актуальна в принципе.


            1. nin-jin Автор
              26.12.2022 16:28
              -3

              И как он спасает от ререндера всего компонента для обновления одного элемента?


              1. markelov69
                26.12.2022 16:35
                +1

                И как он спасает от ререндера всего компонента для обновления одного элемента?


                Вот - https://codesandbox.io/s/compassionate-darwin-rsivuy?file=/src/App.tsx


              1. markelov69
                26.12.2022 16:40

                И как он спасает от ререндера всего компонента для обновления одного элемента?

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


                1. nin-jin Автор
                  26.12.2022 17:27
                  -1

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


              1. mayorovp
                26.12.2022 17:28

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


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


            1. artalar
              26.12.2022 17:15
              -1

              У мобыкса тоже проблем хватает https://www.reatom.dev/#why-not-x


              1. markelov69
                26.12.2022 17:29
                -3

                У мобыкса тоже проблем хватает https://www.reatom.dev/#why-not-x

                Я ни одной проблемы не увидел, кроме выдуманных и не имеющих отношения к реальности и не к джунам.


  1. c_kotik
    26.12.2022 11:35
    +4

    Можно долго и нудно ругать 3х китов индустрии и обмазываться бенчмарками.... Но факт в том, что в основе их топовости лежит доступность и стабильность для конечного пользователя не зависимости от платформы (а тут стоит припомнить предложение ТС пользователям мака самим тестить его вундервафлю).

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


    1. MentalBlood
      26.12.2022 12:07
      +3

      Так статья и про стабильность в том числе


  1. Alexandroppolus
    26.12.2022 12:23
    +2

    А что насчет recoil? Его, кажется, нет в списке.


    1. nin-jin Автор
      26.12.2022 12:44
      -2

      Если пришлёте код реализации, я добавлю и его в бенчмарк.


  1. yroman
    26.12.2022 12:25
    +9

    Отличное сравнение. Не совсем, правда, понятно, что с ним делать теперь. Про MobX и Redux+Reselect не знает сейчас, наверное, только ленивый, эти библиотеки широко применяются, по ним тонны документации, куча батареек и написанные интеграции с тем же React - бери и делай проект. А теперь взглянем на документацию того же $mol_wire. Там плакать хочется. Что с этим делать? Как это ввести в проект на том же реакте без боли и самописных велосипедов, дабы потом эти велосипеды не поддерживать самостоятельно? Я вот лично не понимаю какой для меня бенефит вкорячивать этот менеджер состояний в проект, в котором работают ещё и другие люди, которые в этой куцей документации разбираться точно не станут.


    1. nin-jin Автор
      26.12.2022 12:51
      -7

      Ответы на ваши вопросы есть в документации.


      1. yroman
        26.12.2022 12:57
        +2

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

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


        1. nin-jin Автор
          26.12.2022 13:15
          -5

          Вы правы, думаю в этом биндинге к Реакту слишком много багов:

          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()
          	}
          	
          }


          1. yroman
            26.12.2022 13:27
            +4

            Сарказм оставьте при себе, пожалуйста. Зачем вы мне привели какой-то кусок кода? Какой-то Component? У меня в проекте с MobX нет никаких абстрактных классов Component, у меня чистые функциональные компоненты, мне не нужны ваши абстрактные классы. Вы, почему-то, до сих пор не можете понять что не так с вашими решениями.


            1. nin-jin Автор
              26.12.2022 13:33
              -4

              У меня в проекте с MobX.. чистые функциональные компоненты

              Это либо наглая ложь, либо беспросветная глупость. К счастью, я слишком плохо с вами знаком, чтобы сказать наверняка. Но на всякий случай оставлю ссылку: https://ru.wikipedia.org/wiki/Чистота_функции


              1. yroman
                26.12.2022 13:42
                +6

                Неудивительно, что у вас проблемы (которые вы сами признавали), с такой-то токсичностью. Разумеется, компоненты обернуты в observer. Что не мешает им самим без этой обертки оставаться чистыми функциями. Дело-то не в этом, в общем-то. В чём тут дело я уже написал, но вы упорно не желаете это видеть, а вместо этого кидаетесь каким-то своими кусками кода. У вас интересные и смелые идеи (с тем же Suspense API), но с таким подходом и таким отношением к людям вы далеко не уедете. Всего хорошего.


                1. nin-jin Автор
                  26.12.2022 13:49
                  -5

                  У меня-то нет проблем. Это вам приходится к "протестированному и рабочему" Реакту какие-то костыли сбоку прикручивать, чтобы он не тормозил. Что не удивительно, раз даже пару параграфов из Википедии не осилили.


                  1. yroman
                    26.12.2022 13:52
                    +4

                    >> Здравствуйте, меня зовут Дмитрий Карловский и я… крайне плох в построение социальных связей, но чуть менее плох в построении программных.

                    Ну да, ну да :)

                    И кстати, реакт в моем проекте как-то не тормозит. По крайней мере никто не жаловался, клиенты довольны. Что ещё нужно?


                    1. c_kotik
                      26.12.2022 14:08
                      +3

                      Значит вы неправильно им пользуетесь, ибо у автора все тормозит, глючит и ломается. А значит он все делает правильно. /sarcasm


                    1. nin-jin Автор
                      26.12.2022 14:35
                      -4


                      1. c_kotik
                        26.12.2022 15:23
                        +1

                        Ну вот же - у вас отлично получается язвить! Вполне хорошие социальные навыки. Чего скромничать.

                        Но в плане разработке... вы можете лучше. я в вас верю!


                      1. nin-jin Автор
                        26.12.2022 16:02
                        -5

                        Только это совсем не шутка..


              1. mayorovp
                26.12.2022 13:57

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


                1. nin-jin Автор
                  26.12.2022 14:21
                  -2

                  PureComponent - это имя класса в React. Не смотря на название, никакого отношения ни к чистоте, ни к компонентам он не имеет. К функциям тем более.


                  1. yroman
                    26.12.2022 14:36

                    А такой?

                    function Recipe({ drinkers }) {
                    return (

                    1. Boil {drinkers} cups of water.

                    2. Add {drinkers} spoons of tea and {0.5 * drinkers} spoons of spice.

                    3. Add {0.5 * drinkers} cups of milk to boil and sugar to taste.

                    ); }


          1. mayorovp
            26.12.2022 13:55

            Вы правы, думаю в этом биндинге к Реакту слишком много багов

            Ага, и вот вам первый: при изменении props или даже state компонент более не обновляется.


            1. nin-jin Автор
              26.12.2022 14:02
              -6

              Это не баг, а фича. И в статье объясняется, зачем сделано именно так.


              1. mayorovp
                26.12.2022 14:10

                Ага, "объясняется". Точнее, упоминается что это сделано ради колбеков, а данные через свойства не передаются.


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


                PS вы же в курсе, что в ваших статьях не работает поиск? Когда почините уже?


                1. nin-jin Автор
                  26.12.2022 14:50
                  -6

                  Вы прочитали по диагонали и ничего не поняли. Попробуйте прочитать по второй диагонали - это восполнит потерянную информацию.

                  Где это поиск не работает?



  1. serginho
    26.12.2022 14:15
    +3

    React + Mobx + TypeScript = Love


  1. artalar
    26.12.2022 15:05
    +2

    У меня на m1 и телефоне за 200 баксов реатом быстрее мобыкса ????


    1. LyuMih
      26.12.2022 17:48

      Огонь. Хороших библиотек должно быть много)


  1. LestaD
    27.12.2022 12:54
    +2

    Каждый автор СТМ пишет свои бенчи и именно его библиотека в них всегда выигрывает. А запускать миллионы апдейтов в бенчах и кричать, что там кто-то самый медленный это лицемерие.
    Тот же 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 стейт-менеджерами это конечно очень смешно.
    Никакой из инструментов перечисленных выше не пытается быть серебрянной пулей. Все решают определенный скоуп задач для определенной аудитории. А ставить в один ряд очень разные инструменты это конечно бред.

    Предлагаю снова думать своей головой. Спасибо, за прочтение!


    1. PavelZubkov
      27.12.2022 14:30

      Достаточно открыть примеры кода на $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 разных фреймворков/библиотек?


    1. nin-jin Автор
      27.12.2022 21:12

      А запускать миллионы апдейтов в бенчах и кричать, что там кто-то самый медленный это лицемерие.

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

      будет ли кто-то писать на $mol ... Достаточно открыть примеры кода на $mol ... Вот референс https://mol.hyoo.ru/

      А $mol тут каким боком? В $mol пространстве имён сотни ортогональных библиотек. Упомянутая в статье $mol_wire - лишь одна из них. Использовать её я никому тут не предлагал.

       Как пример, нужно обязательно переопределить base64 encode, но не написать реализацию.

      Реализации под ноду, браузер и тесты для них лежат рядом.

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

      Вы и без бенчмарков прекрасно обманываете читателя, не приводя никаких пруфов:

      А всё потому, что Эффектор сливает во всех бенчмарках. Вот ещё пример с todomvc:

      Назвать Preact, SolidJS и effector стейт-менеджерами это конечно очень смешно.

      effector это НЕ стейт-менеджер, это штука гораздо более полная. В сообществе его называют data flow manager, и СТМ это лишь часть его.

      Вывеску поменять забыли:

      Но совершенно не важно, что как называть. Все библиотеки тестировались в одинаковых условиях на одинаковых задачах.


  1. qweered
    27.12.2022 13:11
    +1

    Добавьте Zustand к сравнению


    1. nin-jin Автор
      27.12.2022 13:16
      -2

      Присылайте код - добавлю.


  1. artalar
    27.12.2022 15:17
    -1

    @nin-jinпоменяй КДПВ пожалуйста, меня гнобят из-за нее.


    1. nin-jin Автор
      27.12.2022 15:19
      -1

      Кто и почему гнобят?


      1. nin-jin Автор
        27.12.2022 21:37
        -2

        Нашёл.

        Внесу ясность по поводу картинки и того, как я вижу ситуацию в индустрии: пока малолетние дебилы React и Angular спорят о том, что лучше Redux или RxJS, а Vue не вдупляет о чём спор, батяни $mol_wire и MobX смотрят на резвящихся малышей, один из которых оказался более резвым, а другой жалуется на попаболь, опять.


  1. Shoom3301
    28.12.2022 15:44
    -1

    Как же ты уже заебал срать своим молом.
    Фу как грубо? Да.
    Этот даун Дмитрий не воспринимает никакой фидбэк и критику, только гадит толстым троллингом и своим низкосортным "изобретением".
    Пора бы его уже забанить, тошно видеть его высеры.


  1. klvov
    28.12.2022 22:28
    +2

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

    Здесь, как я понимаю, предлагается задуматься о штуках, которые еще не дошли даже до мэйнстрима, и только-только доходят. Исторически мэйнстримом сначала было то, что называется сейчас "системным программированием" (ассемблер и машинные коды), потом было процедурное программирование (Си и Паскаль), потом так называемое "объектно-ориентированное" в виде 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 и остальном, идущем в нагрузку.