How are signals implemented?
Hi all! Just saw Theo's latest on Vapor and got curious: how would one go about implementing signals? By that I mean how does Solid/Vapor tracks which elements called the signal to update later? I can see how that would happen in something like Svelte, which has a compiler, but from my understanding that's not how Vue/Solid do it, right? Then how can the framework figure out the which HTML element (or maybe it happens in the component level?) is associated with that specific function call (e.g.
count()
)?
I tried checking out how Solid's createSignal() works (https://github.com/solidjs/solid/blob/main/packages/solid/src/reactive/signal.ts#L1300), but I'm having a hard time figuring this out without a wider understanding of the framework, so I'm hoping y'all would be interested in figuring this out with me!
As expected, it looks to me quite a bit like your usual observer pattern (i.e. this.observers.push(Listener)
in line 1292), but I still can't figure out how that would eventually map out to the DOM. Like, Listener
is a global (line 54), which is assigned to listener
when creating a root (line 142)... But in line 173 it's just listener = Listener
??? 💀
As you prabably can infer, I'm waaay out of my depth here. I'm not nearly experienced enough with Solid (and possibly even with Typescript) to make sense of this (what even is the "root" being created here, in Solid? Does it have anything at all to do with what I assume "root" to be, coming from React?), so I was hoping we could learn together, as it'll probably take me quite a while playing with Solid and reading the source before I can grasp what's going on here on my own.
Also, I'm just using Solid as an example to learn about signals, so I'd be delighted if anyone knew of a simpler/more straightforward implementation of the concept we could use to figure it out (and then maybe come back to Solid knowing what to look for, to figure out whether it's similar or distinct).GitHub
solid/packages/solid/src/reactive/signal.ts at main · solidjs/solid
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid
Solution:Jump to solution
Learn Reactive Programming with SolidJS | Course by the Creator of ...
SolidJS uses its Reactivity to make fine-grained subscriptions which only update parts of the DOM on changes, instead of doing heavy DOM diffing.
13 Replies
SolidJS
YouTube
Intro to SolidJS reactivity (in 5 minutes)
An introduction video that walks you through Solid's reactivity in under 5 minutes.
(in theory)
the algo to handle that is quite simple and easy
the tricky part is making a good dx-wise
most of the time you have a compiler for that (svelte, solid, vue vapor)
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
you can take the compiled output, or build locally, and track everything from there
Solution
Learn Reactive Programming with SolidJS | Course by the Creator of ...
SolidJS uses its Reactivity to make fine-grained subscriptions which only update parts of the DOM on changes, instead of doing heavy DOM diffing.
the preview is quite nice to understand a little bit more
oh, so they all use compilers, then? okay, I can see how that would work.
Yep
most of the current solutions have compiling
svelte, react (to some degree), solid, angular
nice resource, kinda knew that already but a great explainer regardless
Okay, you kinda lost me with React and Svelte side by side there... I'm fairly familiar with Svelte and React (and Next.js and SvelteKit) from that list, and although the DX is fairly similar, their build steps are quite different, right? From my experience/understanding, the build step in React-based frameworks usually packages (i.e. bundle, minify, code-split, etc.) the transpiled TS/JSX without really rewriting it, while Svelte's build step rewrites a lot of code from the .svelte files, somewhat like what TS does.
Honestly, writing this I've realized I haven't had to understand what my React framework is actually doing when it builds since the dreadful days of CRA and Webpack, so maybe I'm misunderstanding/underestimating how much of a compiler framworks like Next.js really are?
Or is Solid somewhere in between React and Svelte in that sense? Where it does some inspection of the source to figure out where the sinal's being called but won't rewrite your code as agressively as something like Svelte
Okay, awesome, I think this is exactly what I wanted to know -> https://frontendmasters.com/courses/reactivity-solidjs/creating-a-signal-from-scratch/
Learn Creating a Signal from Scratch – Reactivity with SolidJS
Ryan creates a reactive signal from scratch. A global context array is used to store a list of observers that are subscribed to the signal. When the signal is updated, each observer's execute function …
And taught by the man himself!
Thanks a lot for the resource :)
Seems like I'll have to buy the course to get my answers haha 🥲
I can answer the question
Sorry took me a few days to notice.
Generally Solid is mostly runtime. The only compile time trick we use is in the JSX where we look to see if you call a function (or access a property) and then we compile it to a getter/createEffect instead of just setting the value.
So rather than looking at it like between Svelte and React.. it might be more like .. more React than React
Atleast where things are heading with them.
Signals are independent of rendering and have a defined behavior that is pretty out in the open. Very what you see is what you get. There are tradeoffs to that as you need to be aware of function wrappers a bit. But on the magical scale I'd say we are the least magical.