Update (2024): Dev.to recently broke their svg renderer, so I've hosted a copy of this on my personal site https://milomg.dev/2022-12-01/...
For further actions, you may consider blocking this person and/or reporting abuse
Awesome work.
I like that you looked at the difference between width and depth. A lot of reactive benchmarks focus on depth, but most reactive UIs are actually wider than than they are deep from a reactive perspective. Like how far do you derive a value, 2 or 3 levels tops, where these benchmarks tend to look in the 1000s. But having the same value read in 10s or maybe 100s of places in the UI is more common.
I look forward to how we can make a system like this work with concurrent rendering.
I'd like to see how Sloid does on these
Benchmark against
@maverick-js/observables
please. It also claims to be the fastest.github.com/maverick-js/observables...
I don't think they are claiming that anymore. Looking at their benchmarks Preact Signals are faster than them in those depth based tests.
Also Jin added Reactively to his benchmarks too and it topped it:
Definitely should test it, but Reactively seems to holding up well.
It's probably not very important anyway - any of these libraries are more than fast enough. Unless you were building a highly real-time application (like a game) the difference likely wouldn't be measurable in real-world applications.
But since clearly it's a contest on metrics, claims like that should be backed up - for those people who are picking a library based on its performance. Most of us probably should pick based on merit rather than metrics. 😋
From what I remember, the current solid algorithm also does coloring, to figure out priorities but then it updates all un-updated memos anyway for predictability. Is this somewhat correct?
That's correct. The current Solid algorithm pushes all updates into a queue and then gets each item in the queue using the same coloring algorithm as Reactively
Solid today over queues, but it doesn't run any unnecessary computations. Basically it iterates to check the state of nodes more than it needs to as it 1. faster than sorting, 2. easier to interrupt for time slicing.
Let's translate it to rust and then create a DB out of it.
A Rust implementation would be interesting!
When will the second part of the benchmark be posted? Looking forward to comparing the data structures each framework uses!
Bad.ass
Hi! The bench approach is very interesting, thank you for sharing this!
But I can not reproduce example from the readme, your package just have no "reactively" variable in the sources, looks like this is the bundling issue?
Also, the important question IMHO, is Reactively support atomicity guarantees for state consistency or could it lead to unpredictable behaviour if error occurs?
Ah yep, looks like what might be missing from the source is
As for atomicity:
One of the really neat benefits of lazy state is that you don't need batching or atomicity within a transaction for consistency. However, it is still necessary to be able to catch errors and rollback. Currently Reactively doesn't support rolling back, but it should be possible to add in a future version.
I think atomicity should be default (as React.js fails all render which cause an error) . The problem with reactive programming is that error propagation is not obvious and could lead to really bad cases, here is a simple example
Hey, thanks so much for the article! I found it extremely informative.
Curious how you found out about the internal implementation of MobX? I'm currently diving into the codebase but I'm having trouble seeing how in code how it tackles the diamond problem... I'm most likely not looking in the right area
Thanks for the kind words! It looks like since MobX 2.5, MobX has switched to a model with lazy computeds, and currently uses a similar algorithm to Reactively & Solid. Because of this, computeds are pulled on demand instead of evaluated eagerly so to avoid evaluating A in the diamond twice, it just needs to mark it as clean/up to date after the first evaluation. The original version avoids overevaluating any element in the diamond by predicting how many times it would be reevaluated (how many parents would update), and then only updating once that many parents have already been updated.
Here's the source of where MobX used to mark dependencies as stale: github.com/mobxjs/mobx/blob/2.4.4/...
You can compare that with the modern implementation using STALE (red), POSSIBLY_STALE (green), and UP_TO_DATE (gray): github.com/mobxjs/mobx/blob/v6.0.2...
How come RxJS is not included? The most obvious choice for reactivity IMHO
RxJS has a slightly different API and semantics that don't match the rest of the frameworks in the benchmark. For example, it has no concept of a computed & signal.
That being said, I would be open to a PR that adds RxJS to the benchmark (these are the files that you would need to modify github.com/modderme123/reactively/...). It should be possible to do that pretty quickly using something like github.com/kosich/rxjs-autorun.
Did you shared the benchmark structure you created in any place?