DEV Community

Discussion on: The Cost of Consistency in UI Frameworks

 
webreflection profile image
Andrea Giammarchi • Edited

Synchronously updating the DOM could be fine if you do basically no work but update the DOM

that's what every framework and library does at some point in time ... but you do it without scheduling updates, and that's an issue because you might involuntarily trigger repaints and reflows while executing JS ... Solid.js here is as bad and blocking as accessing element.offsetWidth could be, because a state can cause other DOM parts to move right away so you'll have, on a complex stack, 10+ blocking things instead of maybe 1 or two, because style changes are scheduled next paint tick anyway, unless you force re-calc there, and Solid.js will never be able to batch (the topic of this post indeed) all changes at once.

You made a choice to use callbacks and you have pros and cons, but it'd be great if you could recognize the cons ... and blocking the DOM per each state change is a HUGE cons to me, and I didn't know, so I was surprised you wrote this as if Solid.js was cooler (I know you didn't mean it ... but you know, you kinda tried hard to justify that 1 2 2 and I tell you, that 1 2 2 can be a real-world performance issue in scenarios textContent is not the only thing involved in the state change).

Feel free to ignore my comment, or maybe rethink scheduling in Solid.js because this thing I've learned today is a pretty bad news to me, something I believe if properly tested in js-frameworks would push it down the slope with extreme ease.

Thread Thread
 
webreflection profile image
Andrea Giammarchi

P.S. custom elements attributes changes, as well as connection and disconnection events, are synchronous and blocking too ... if a state change an attribute and you have a reactive chain in there, for a single state change that maybe involved the whole stack you'll have a clunky experience due blocking and undesired things moved around.

Maybe for 95% of sites out there this is not a real concern, but if everyone else went for a non directly blocking approach when a state gets updated, there's probably a reason behind ... right?

Thread Thread
 
naasking profile image
Sandro Magi

it looks like with Solid, the same operation via count() + x will result into 3 DOM updates instead, no scheduling ... that's slower, and a pattern you chose, not the best one for sure, likely the worst out of the 4 libraries or frameworks you decided to compare in here.

Gotta disagree there. You're effectively saying that given a choice between correctness and performance you should choose performance, without even evaluating whether the correct solution's performance is sufficient.

JS is a wildly mutable language. The contexts in which you might be accessing state are uncountable. Solid preserves consistency of the dataflow graph when accessed from all contexts and is consistent with JS mutation semantics. Therefore it's approach is the least surprising and most flexible, able to slot in where you need it. It is clearly the right default, and should only be bypassed when profiling actually demonstrates a problem.

Thread Thread
 
webreflection profile image
Andrea Giammarchi

given a choice between correctness and performance you should choose performance

I chose correctness like I've already mentioned ... my libraries chose correctness which is the safest bet as the OP wrote.

without even evaluating whether the correct solution's performance is sufficient.

The first version of uhooks was synchronous and it's been profiled, benchmarked and tested until the point it became like React, so that all states that changed in an entire stack call would side effect with a final state once (as effect) and that was both correct, more predictable, but also enables fiber/suspense like patterns but again, effecting synchronously plays badly with Custom Elements and some other HTML or SVG attribute, but also I never talk or expose concerns by accident, too many years on reactive patterns and yes, I made my choice there.

It is clearly the right default

Not to me and apparently not for React neither, where hooks come from. Maybe solid should stop comparing its mechanism with hooks, as it's clearly too different there, for better or worse.