Signals Explained
HTML-код
- Опубликовано: 25 авг 2024
- How signals are implemented and what are their benefits.
💬 Topics:
- Implementing Signals, Computed Signals and Effects;
- State management in web apps;
- Dirty checking alternatives;
- Why is Solid so fast;
- The benefits of using Signals.
#javascript
Patreon: / awesomeclub
Way back in ancient history, before react, when angular 1.5 was king. I wrote a signals library which worked very well for enterprise grade architecture. Before that in fact, when everyone was crazy about message busses, as an alternative I wrote a signals implementation for a Flex (and parsley) application which was being used in investment banks. It was about 40x faster than the standard message bus solution. The point is, signals are nothing new. It’s just fun watching the development community rediscover, iterate and improve on these architectural patterns. I wonder what cool stuff people will be doing next 🤔
Pinning this comment for the Flex application reference.
Flex… it was a blessing at the time, yet also a pain😂
actually a signal is no more thant a event, a delegate or a oop-callback
I too feel weird JS community is saying this as though is some kind of new discovered thing. I'm sure many folks have intuitively implemented this one way or not.
Amazing. Signals in practice are a little more complex but this is the bare minimum to get the same effect. I am enjoying these technical deep dives ❤
Thanks for the feedback!
I'd love to get even deeper into some of these topics, but there is only so much you can do in 5 mins without becoming "too boring" 😅
@@awesome-coding yeah I understand
We need more videos explaining concepts we use everyday but don't really understand! This was really helpful!
Glad to hear! I have a long list of concepts planned for this video series.
This is so interesting, Vue has had this concept since the beginning and finally everyone else is catching up 😅
Vue is king, but left out so much
This will be an amazing series, this was a great bare-bones explanation!
Glad you enjoyed it! Thank you for your feedback!
Fantastic, your content is getting better and better, keep it up.
I really appreciate it! Thank you!
Great video! I didn't really understand this at first but then I tried to do it myself and I get it now. And now I realise I actually tried to implement signals before and just didn't realise it, although it wasn't very good and you had to manually pass the dependencies. But I managed to come up with a much better solution thanks to your video, especially since I didn't understand how to keep track of the dependencies.
Can you make a video going more in depth on the topic? I wonder how you would better check if the value is the same because if you just use === it will run effects when both are NaN or either are null or undefined. And as for better dependency tracking, I noticed that the effect function will trigger twice per update because it tracks both effects but one depends on the other.
Glad you found this useful!
Yep - auto registering dependencies requires a bit more focus, but once you get it you "really get it"
Note that there is an argument to be made for manually registering dependencies as well. Auto registering might feel like magic, but they require your code to run once to have everything in place. Manually registering the dependencies, is more imperative, but you have more control over the whole execution.
I'll dive deeper into the topic for certain.
Thanks for your feedback!
Thank you for the great content
Glad you enjoy it!
Great video!
Thank you!
So it is automatic subscription basically. How do you automatically unsubscribe?
The code is way nicer with signals, but there's still an issue. We have to do this kind of dirty `document.GetElement` and `addEventListener` logic. Is there a way in which we could avoid having to write that imperative boilerplate? When you think about it logically, it definitely should be possible, but how?
Ive enjoyed the way svelte handles state the best imo :)
Fair enough! I know their DX is great!
What I don't understand is the difference with useState in a framework like React. I believe they're nearly the same but signals seem a little bit better. What I don't understand is why the community gets so crazy with signals when its only a more optimized version of usestate which we've been using for a long time now.
I don't really understand the benefits of signals over useState to be honest. You talked about it in the video, saying signals only update the component when their value changes, but isn't it the same with React ? I mean a React component only updates when its state (and props) updates. What do you mean by "dirty checking" when saying "signals > dirty checking" at 4:19
I'm sorry but I don't really understand
I'm not an expert but let me try to explain the differences which causes performance boosts. With a react component there are multiple states/props bundled in a component. If any change, the entire component function reruns. Signals are more sergical where dependencies are tracked closer to where they are used. There are also other benefits (like not requiring react's shadow dom) but this is how I think of the difference.
You can build the exact same things with react vs signals, but it is (probably) less efficient, and (probably) has more footguns since multiple states variables are bundled.
Pretty much: React always renders again, and the hooks are always called. Then it does the dirty checking every time inside the hook function before deciding what values to return.
Signals only react when things happen, and only the things that actually depend on it.
Svelte is using observables, right? What are the advantages of signals over observables?
I think in Svelte 5 they're moving to Signals and it's supposed to be faster.
Signals are "synchronous" while observables are "asynchronous". This is a fancy way of saying that signals always "hold" a value (so you can do signal.value to get the current val) while observables are just a container that emits values (think of a water pipe - the pipe is empty inside, and it'll throw out water from time to time). So while signals hold values you can compare them (just like I did in the video) at any given time and make the updates. Observables need to be paired to some other mechanism that stores the state, then states snapshots need to be compared to figure out DOM updates. The snapshot comparison (dirty checking) is always slower than signal value comparison.
Thanks for this great explanation!😊
Signals are reactive, but synchronous. It's a much simpler problem than what `RxJs` is solving, so the api will be simpler :shrug:
A great fit for typical value updates, but not great for managing inherently async things like events. Hopefully it doesn't become the new hammer for every 'reactive' problem.
Good points!
This should look very familiar to anyone Vue's composition API
Yep!
So signals are some kind of enhanced observers
Another great video! Regarding signals; smells like over-engineering. One could just use a class setter for the counter and call the update function there.
Setter and getter is in fact how Vue’s reactivity works prior to v3. Vue under the hood will deep convert every item into a getter/setter. One pain point of this is that you cannot simply add new item to the object because doing so does not go through the setter function, and Vue will not be able to track such changes. That is one of the main reasons why Vue moved to ES6 proxy in v3
Edit: Reactivity only breaks when adding new items. Modifying existing ones doesn’t
@@phb7876 interesting. All these mechanisms make sense for general purpose front-ends as they try to guess what DOM to update but, from a pure JavaScript perspective, it seems irrelevant because you as the Dev, always know exactly what DOM should be updated. Worst case scenario, you write a simple function to update the counter and DOM and always use that.
@@netssrmrz That might work in simple scenarios where a state is only used by a couple of DOM elements. When a state used by multiple elements rendered by different components, it becomes a pain in the ass to manually keep track of. And that is why these general purpose method exists
@@phb7876 I believe that to be a common misconception. On various enterprise level projects, I've converted plenty of react components into raw Web Components (no framework) using these simple techniques and the code is always smaller and faster. There's no "maybe" in my opinion. Conversely I've seen plenty of complex react components that were slow and unreliable exactly because the data binding and context were so complex as to make it impossible to know what code would be executed and how many times. Everyone should try the simple techniques first and prove them for themselves.
good presentation 😄👍
Thank you!
how does this compare to having a reactive value statement $: updating the value in a store in svelte? thx 🙏
Vue uses proxies, probably an easier approach but people may be more familiar with vanilla JS classes indeed (I hope so 😱😂).
Good video. 👍🏻
Good point! Thank you for the feedback!
More precisely, Vue *3* uses proxies. Vue 2 was implemented with `Object.defineProperty()`.
Are these signal and effect functions part of native JavaScript ?
No they are not - you need a 3rd party library, or your on implementation to use them.
I wanted to ask how this is diffrent from Observable or Subject but you mentioned them.
Diffence is in the ease of use, automagical registration combined with proxy get/set like in vue.
I hope in real life that is not done by global variable :D but it clearly explains concept.
Simillar tricks were used when stack track was not available at debug to track where program currently run.
In most frameworks with function components, it's basically handled by the difference between functions and arrow functions in javascript. Non-arrow functions have the implicit this parameter which is used for the automatic registration, and are used for components in the frameworks that use signals
The way to do it in other languages is usually to use something like dynamically scoped variables, contextvars, or effects
Hi, how do you create the animations for this tutorial?
Like, the hand icon that points at parts of the code and moves around?
Which software/tools did you use for these?
Thanks :)
Hey! I'm using Adobe Premiere to edit the videos.
@@awesome-coding Oh, I thought it was After Effects. So it turns out to be Premiere Pro. Thanks.
can we achieve same result using Proxy object In javascript ?
Yes - Vue refs are very similar to signals and they are implemented using Proxies /
is this similar to the provider pattern?
Non of those frameworks give the freedom of
importing VanillaJS libraries with 2 lines of code,
like Svelte does.
Svelte can compile its simple reactivity style to anything,
including signals if the main contributors see it fits.
So this Svelte code will always compile to the best thing no matter what year it is
```
let counter = 0 ;
$:double = counter * 2
```
Svelte is indeed the king
Svelte kinda does dirty checking ( but in a more intelligent way ) but this is changing and the next version of svelte is going to be as fast as vanilla js or solid
Good point!
agree!
You stole my comment. But yes. These frameworks keep running away from web development to become "x-framework development". Long live the king Svelte.
so it's basically mobx?
I think is the other way around. Signals are more of a design pattern / architecture detail. MobX is a library implementing, among others concepts from this design pattern.
I don't understand what context is
Looks like event-driven programming is in again
Was it ever "not in"? 😅
i have been using leptos in my spare time. the solid/solidstart clone in rust. according to js framework benchmark it's faster than all of the js frameworks with the exception of solid since it follows the same approach. on the server it's obviously not close in rust's favor. leptos is less complex imo than the js meta frameworks too. the dx is next level.
This is true only once you have a good understanding of Rust, a language known for its complexity.
I believe it's hard to argue in favor of Rust as an alternative in the JS community.
@@awesome-coding i don't think it should or will replace js/ts. i can see it gaining some traction for niche apps where teams want additional type safety and security. essentially the new elm but on a larger scale since it's actually supported by the browser and is a much more popular language in general with use cases outside of the web.
Could you please do some videos on AWS architecture stuff?
I actually have some cloud videos planned! Thank you for the suggestion!
HI, thanks for the video.
Few things to point out:
. are writing in js or ts, because private key word does not exist in js, if you want a private prop / field in class base in vanilla js, you should use '#'.
- Why every video or post about signals mention that Vue is signal base ???? that is wrong . vue 3 use proxy browser API .
Hi!
Nice catch - that's TS, but I messed up and made it a "JS" file in the video editor.
Correct me if I'm wrong but while refs use Proxies under the hood, their implementation is conceptually the same, right? You "track dependencies" on get and "trigger dependency updates" on set. So, while Vue's implementation is not called "signals", it's still pretty close to the pattern presented in the video.
I guess where I failed was making Vue seem like they just "adopted the Signals idea", while they were actually pretty much ahead of most of the other guys in implementing this.
@@awesome-coding HI, in Vue 2 maybe however in Vue v3 definitely not the same concept. Because Vue use a native Browser API like proxies and second no need for Compile-time reactivity, as such no need build tool if you did not want. Better explanation in Vue docs about "Reactivity in Depth".
In other hand what make more sense is compare the ways or implementation of signals on solidjs vs preact vs Angular 15+. That comparison make more sense and will do better video in the future,
Why do we need this if we have Svelte?
I don't know why we need it, but Svelte itself clearly needs Signals since they'll be adopting them in their new major release :)
Can you please explain Unit Testing in Angular ?? Please. Its Docs is very very toughly given.
Hey! Sadly I don't consider myself an Angular expert, but I'll try to look around for somebody that is, and maybe w'ell do a video :)
@@awesome-coding Thanks for the response. Now it is not needed. I have found one on RUclips. Now I know 80% Unit Testing from WebTechTalk channel and Techsharekk channel. Both these channels are Gold for Angular. 😁
Isn’t this just an abstraction for calling a reference…
:)) This could be said for most design patterns
the fact that there is no one solution for this, that is agreed upon by every framework is troubling
A lot of frameworks seem to get behind this signals idea... for now :)
very interesting but nothing is clear
this sums up my software dev career
Why don't we just use Proxy?
Proxy API - yes, you can use that, and it is a fairly common approach.
Proxy design pattern - yes, Signals follow that pattern.
And svelte5
Yes, now Svelte 5 as well :D
One word: Proxy
yep - proxy pattern at its best
actually, this is nothing more than js-way of events
Mm... is this just a copy+paste of Ryan's 'introduction to reactivity' talk?
I listen Ryan talk a lot about reactivity and signals, but mostly in his live streams. The concepts are pretty straight forward, and was not my intention to "paste" any of his talks. I'm sorry if it looks like it.
@@awesome-codinglol was just about to delete the comment. Ur fast!
@@awesome-codinghe had a talk he did a lot at conferences last year where he coded a barebones reactive setup, like u did now. It used to be a video on the solid RUclips as well, but it got removed bc of the Dan situation (if u know u know).
@@bigmistqke Haha no worries. I appreciate the feedback - it keeps me honest :)
@@bigmistqke I'm like hearing about the Dan situation EVERYWHERE, but I can't figure out what the situation actually was 😅
Nice great explanation 🫡
Glad you liked it!