4 ms·
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 yo
by MrJohz 1y ago
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 2, no SolidJS works basically the same as this. For example, in SolidJS,
<div>my name is {name()}</div>
will transpile to something like (very approximately)
const el = _render("<div>...");
const textNode = el.children[1];
createEffect(() => {
textNode.nodeValue = name();
});
The render call creates the element once per instance of the component (i.e. not rerendering on ever change), and the `createEffect` is doing roughly what `$(() => { /* */ })` is going - i.e. rerunning the function ever time the called signal changes. This means that when `name()` changes, only one specific node in the DOM will change, and no other work will get done, making the update about as fine-gained as it's possible to get.
Aberdeen looks like it should be able to do something similar like
$("div", ":my name is", () => name)
Which I'm guessing would only rerender the "name" node, right? Although I imagine in most cases it's easier to be a bit less fine-gained for the benefit of slightly easier-to-read templates when developing.
I do like this as a no-build alternative to SolidJS, and I think the syntax works really well for creating mini templates. I can imagine this being great for dropping in little components on traditional server-rendered, mostly static pages - no need for a large library, just something providing the bare essentials in a clean way.
You mentioned somewhere that in benchmarks, this seemed to be running at around React performance (albeit a lot more lightweight). I suspect you can get a lot more performance by fiddling with the signals implementation. It might even be worth pulling in an existing signals library as a single dependency, or at least exploring how some of the more performant ones are implemented and taking those ideas. Especially as things get more complicated and you end up with more nested `observe`s, getting that to work efficiently is going to be difficult.
- vanviegen 1y agoYou're right about Solid, of course, I forgot about its compiler doing magic! $("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 <div> (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)).