Earlier quoted context omitted.
> Nice little library, but as it's signals based How do you reach that conclusion? There is nothing mentioning signals in the docs anywhere.
The proxy object is a fairly classic way of doing signals (see Vue, SolidJS), and the whole thing about functions rerunning whenever data that was accessed inside that function changes is pretty much the definition of signals. It looks like the author is trying to avoid making direct comparisons with signals and existing signal frameworks, which makes sense - depending on your target audience, it can be a bit "inside…
Show HN: Aberdeen – An elegant approach to reactive UIs
121–130 of 138 posts
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#122Earlier quoted context omitted.
The problem is that JSX transpilers will put child nodes in an array, instead of in an anonymous function, meaning there is no easy way (without transpiler magic) to rerender just a part of the component. This JSX: Welcome {data.enabled ? : "disabled"} Which becomes this with Babel: _jsx("section", {children: [ _jsx("h1", {children: "Welcome"}), data.enabled ? _jsx("input", {}) : "disabled" ]}) But we'd need somethin…
Your `_jsx` function can auto-wrap children in a function. Also, you can just pass functions as children, too if you really want to make the JSX author work for it: Welcome { () => data.enabled ? : "disabled" } That doesn't even look half bad to me. It looks really close to many of your other examples. > In React you can, with some effort, limit virtual DOM rerenders to a single component. Aberdeen rerenders fraction…
It unfortunately can't, because by the time the jsx function gets a chance to run, the expression has already been evaluated, whereas the whole point of a framework like this is to be able to run that evaluation repeatedly.
So what you'd need to write to get that to work would be something like
{() => user.name}
for every single case where you're interpolating a value, which starts looking kind of ugly. It also has its own pitfalls. For example, your example with a ternary in it would unnecessarily rerender (i.e. completely unmount and recreate) the child elements if the input changes but the conditional still evaluates to the same thing. (E.g. if data.enabled was 1 and we set it to 2, what we want is to have no change in the DOM, but what we'd get the input element being unmounted and remounted.)There's also just the general issue that JSX requires some sort of transform. This isn't necessarily bad - I use SolidJS a lot which explicitly makes use of the chance to optimise the JSX rendering at compile time - but there are situations where you want to avoid that, and having a syntax that's focused on the "no compile step" case is useful.
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#123I remember the concept of the virtual dom had to be explained very carefully so people understood why it led to more efficiency when rendering (e.g.) scrolling content. Is there a technical trick that one takes that can beat a virtual dom use case? What is it?
This is always going to be slower than a framework like this or Solid or Vue or whatever, which just skips to the last step and only make the necessary changes in the DOM.
Another way to think about it if you're familiar with different forms if GUI rendering is that React is an immediate mode abstraction sitting in top of a retained mode system. In React, theoretically, the render functions could run at 60fps, constantly churning out the same values. In practice this isn't very performant, so React has its own rubrics for when to rerun the render functions, but that's why, for example, it's fine for React to do its weird double-render thing in dev mode. However, at the end of the day, the DOM doesn't work like that, so React needs to diff everything back into DOMland.
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#124Earlier quoted context omitted.
The proxy object is a fairly classic way of doing signals (see Vue, SolidJS), and the whole thing about functions rerunning whenever data that was accessed inside that function changes is pretty much the definition of signals. It looks like the author is trying to avoid making direct comparisons with signals and existing signal frameworks, which makes sense - depending on your target audience, it can be a bit "inside…
Huh. I guess in my trend-chasing days we just called that event driven programming.
if (showName()) {
console.log(name());
} else {
console.log("the name is a secret");
}
In this case, both `showName` and `name` are signals. If `showName()` is true, then the effect will automatically subscribe to both signals, and this function will rerun every time the name changes, or someone toggles `showName`. But if it's false, then the effect will only subscribe to the `showName` signal, which means even if the name changes somewhere else, that won't affect this expression at all.In complex situations, it can be harder to see where the reactivity is flowing without the explicit subscriptions, especially at first, but it's also a lot more intuitive to just use data and have it automatically become reactive where it makes sense. It's also the base for most major web frameworks outside of React.
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#125Earlier quoted context omitted.
> Nice little library, but as it's signals based, it would be nice to make it compatible with the signals proposal ( https://github.com/tc39/proposal-signals ) Based on the current proposals, it seems that a signal can only contain a single atomic value, for which changes can be tracked. Aberdeen's `proxy` can efficiently wrap complex data structures (objects within arrays within objects, etc), tracking changes on th…
Aberdeen's proxy is essentially an object of nested signals. In general: proxy({ name: "Foo", email: "bar", }); is semantically equivalent to new Signal({ name: new Signal("Foo"), email: new Signal("bar"), }); The syntax for getting a value will look different in each case, but using Javascript proxies you can fairly easily wrap the latter in such a way that it looks like the former. That's what happens with SolidJS'…
'Nested signals' it is then. :-)
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#126Earlier quoted context omitted.
Here's what your Mithril examples looks like with Aberdeen: let count = proxy(0); function Counter() { $('div', () => { $('h1:Counter'), $('p:'+count.value), $('button:+', { click: () => count.value += 1 }), $('button:-', { click: () => count.value -= 1 }) }) } $(Counter); // Or just Counter() would work in this case The '.value' is needed because we can't proxy a number directly. This extra step goes a way if you ha…
Thanks for the example. I agree they look very similar, which is what dsego saw intuitively and commented on. The difference in the two examples is essentially whether things need to be proxied or not. If someone does not mind that proxying, then Aberdeen has an advantage over Mithril by avoiding the complexity of the vdom internally. So, presumably the rendering code is simpler, which may have some benefits in perfo…
Whether that's significant depends on what you're building of course.
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#127Congratulations on the launch! Have you considered any sort of templating like htm or JSX? Because it's a bit harder to read and I believe to work in a team it would be much simpler if there was a template syntax.
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#128It looks influenced by JQuery
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#129Earlier quoted context omitted.
Thanks! Yes, there's some similarity to Solid.js, but also two big differences: 1. A Solid.js signal contains a single atomic value that can be subscribed to, while an Aberdeen proxy can wrap around a complex object (containing arrays containing objects, etc), and subscribe to only the primitive values that were read. 2. If I understand correctly, Solid.js can only redraw entire components (which may not be great at…
Re 1, SolidJS also has a `createStore` primitive which works the same as your $proxy. That said, based on your other comment that I relied to, it sounds like your internal signals implementation is based on the nested, mutable object case, which is fascinating - I believe most other signals implementations go the other way round, starting with atomic signals and then nesting them to create fine-grained reactivity. Re…
$("div", ":my name is", () => name)
Close.. but $() doesn't act an return values of function arguments. You'd need to do: $("div:my name is", () => $(":"+name.value))
Or: $("div:my name is", {text: name})
Or, if indeed you don't care about recreating the (which would normally be the case): $(`div:my name is ${name.value}`)
Re performance: Aberdeen is already pretty well optimized, so I don't think a lot more could be squeezed out. Aberdeen performs pretty well on js-framework-benchmark, but not spectacular. There's a certain amount of overhead involved in having many fine-grained observers and fine-grained observable. What you gain from that, is a lot more flexibility in where state can live, and not having to worry about things like memoization.Where Aberdeen does really shine, performance wise, is reactively displaying lists ordered by some specific function. Other frameworks generally require a sort() and complete list VDOM redraw for each little change, while Aberdeen can just redraw a single row (using a skiplist to determine its (new) position in O(log n)).
Re: Show HN: Aberdeen – An elegant approach to reactive UIs
#130The two downsides you list ("lack of community" and "lack of ecosystem") are not really downsides. If something is good enough, people will simply adopt it out of excitement, and those two problems will disappear entirely. See Rust and React. This looks and sounds incredibly clever, and seems to be what I always wanted React to be. I'm eager to try it out! Could you make a demo of a simple Todo list app in it that le…
I think what you're looking for is mithril. It checks every one of these boxes, except it has a nicer developer experience and still has lifecycle methods, which seem much easier to reason about and test than Aberdeen. Seriously, check it out. You'll be impressed. You can learn the API in a day, and it's super stable and thoughtful. I've been using mithril for a decade and the only time I don't reach for it is if web…