I love these intermediate-level videos. So much content is aimed towards beginners and the advanced content gets complex real fast. This strikes aa nice balance
To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/JackHerrington/. The first 200 of you will get 20% off Brilliant’s annual premium subscription.
Great video as always Jack, thank you! Interested in more of such intermediate topics which focus on inner workings of React and other libraries, and how it effects performance and developer experience etc.
The first is somewhat similar to the vue3 proxy responsive principle, the second can use structureClone, the third point if you prefer to directly modify the mental model you can use immerjs
Never been disappointed watching your videos, Jack.. been over two years I think, every video I have watched, I have learnt a thing or two.. am so grateful to you..
I've been thinking about this recently, thank you for the informative explanation. It was an awesome video. I look forward to more videos delving into the intricacies of the subject.
It's been a while since I've doing one of these more "theoretical" videos. It was fun to do. But it's always a crap shoot as to whether it's going to perform well.
To the viewers : don’t build your own state manager. Valtio provides an amazing High Performance proxy state manager that is super simple to use properly: th-cam.com/video/gGY9HvUe2AA/w-d-xo.html
I dont know how you come up with this ideas but... keep going. please. At the beginning I though that this video was more oriented to the 3 state management paradigms (proxies, atoms and flux) but was a surprise how it ended up!
I honestly prefer React's immutable approach. I like to treat every object as Object.freeze( ), so mutating some object directly feels weird, even more so if I have to mutate it & then set it again.
Just migrated huge app state to Valtio yesterday from zustand. Initially I liked the idea of mutating data right away when needed, instead of defining setters, but soon started having issues with deeply nested arrays and objects. Migrating back to Zustand now 😥
I kinda like proxies, nested proxies are cached as well, so they only get created once, when accessed first, and it should be pretty fast; if we want to update properties that are nested 7 levels deep into a state inside a component I'd say we have bigger problems. An alternative to the [state, setState] separation that would still work with primitives would be to consume a value like we do now with `state` and set it with `set.state({ thing: { to: "patch" }}), but setState isn't at all bad the way it is.
I love lodash and yes it's slower but I had to use it (deepCopy) on an incoming data stream from an ECG with an incoming sample every 2ms and it kept up pretty well. Anyways, I use both lodash and object-path in most of my projects for dealing with deeply nested objects
I'm Brazilian and have difficulty keeping up when the explanation is very fast. I enjoy your videos, but it's hard to understand. It would be amazing to watch videos with a slower pace for non-native speakers. tks
Hi, Does react compare the mutable statetypes for rerendering, in the addAndCompareReference comparing two objects using "===" operator is a bit issue too i assume.
It actually uses Object.is, but === is the same behavior. It compares references and NOT contents. React itself does NOT care about the contents of your arrays or objects when it comes to state management.
@@jherrSignals are by reference, Stores are proxies. And I guess the performance gain is probably more from explicit changes in the reactivity model instead of React just doing everything again because something, somewhere changed
I think people doesnt give enough credit to hookstate, where do you stand on this Jack? It uses proxy and if you use it with useHookstate hook, you can observe nested objects with class getters and setters. Thanks for the great videos by the way.
I am wondering how to perfect the data structure of todoist like app. Currently, using supabase I make simple query for project that has sections array, and each section has an array of tasks I also use dnd-kit and I want to achieve the most performant task section change I can make. Currently I keep my project obj in state, when I move my task I use structuredClone and change tasks order and section in this nested messy spaghetti. Todoist uses flat projects, sections, tasks structure, each is a Map Im trying different ways right now and flat arrays and nested arrays have similar results, (0.1 to 0.4ms task drag between sections) I'll try with maps, very fun to work with it
I know you are talking about something else, but you hint at something. DeepCopy from lodash is something like the following obj is of type obj, array, an array of objects, object of arrays, whatever clonedObj1 = JSON.parse(JSON.stringfy(obj)) clonedObj2 = structuredClone(obj)
StructuredClone, which is native clone, is oddly less performant than deepClone. Super weird, but that's currently the case at least with V8. I just tested a JSON.stringify/JSON.parse variant and it's about 2.5X slower than the lodash deepClone/isEqual.
Think that is what I saw when doing my test also. I believe the StructructuredClone is not as defined as some other basic JS, meaning it could be very different per browser. stringfy/parse has the issue js has with strings and might be like regex under the hood. Was thinking more just when you need the initial obj to be the obj, but are not using lodash in your project. Then you do initialObj.something.deep === newObj.something.deep. Maybe you need the initial Object for different parts of the code also, so not just comparing newObj vs initialObj.
I have been using deepsignal (the one where u can just mutate, there are two packages called that...) for the past two weeks and really like it. Is a proxy state built on top of preact/signals.
I didn't run the benchmarks on proxies because I don't think they make a good option for basic state management. Primitive values need to be boxed (e.g. String("hello") vs just "hello"), which nobody is going to want to do, and nested objects and arrays get tricky because you have to mark them as proxied which means setting a special key, which messes up data integrity. It's just nasty. One good alternative would be what Solid-JS does which is to have reference based state management with createSignal, and proxy based state management with createStore. It would be great if React had a built-in useStore.
This made me curious about immer, since I’ve used it for some things, especially with deep objects (and the fact that the object destructuring gets messy in my opinion), and wow, three times slower than deep copy!
I was curious same think and test them, reference compare = 0.504μs deepcopy compare = 5.859μs immer compare = 9.986μs Immer looks impressive, but only for DX However, I'm concerned about its 20 times slower performance compared to reference. Is it worth sacrificing performance for this DX benefits? Btw, immer also has almost 5kb gzip package size.
Hi, nowadays no need loadash to create deep copy, all browser ( this is not part js) you can use structuredClone global fn- Of course in your test this fn will not work, you have to run in browser env. Either way, i dont think that will change the conclusion.
@@bigmistqke did you tested? i always prefer native feature than external libs. And depends on the browser, if you are using safari or FF ya maybe but in chromium base browser is a stretch.
@@jediampm yes i tested it myself, on firefox and chrome bc I wanted to get rid of lodash in website I m working on. It's substantially slower. google it if u don't believe me, it's actually quite established.
@@gordonfreimann Yeah, the preact signals are equally hacky. Any Solid-style signals on a VDOM framework is going to be subverting the framework because you are altering the DOM directly without the VDOM being updated.
If you are doing what I think you are doing then you're just subverting React and you should use Solid-JS instead. Solid was designed to do that from scratch. TBH, for most applications React performance is fine. It's freaky to see that a component function gets re-run when state changes, but in reality, that's very fast since it's just creating some objects which are compared against other objects and when there is a delta the DOM is updated. By using useRef and then changing properties/attributes/content that React would normally do for you, you are just breaking React. And it's not clear why you would pay the price for the download of the React library just to subvert it.
Got it Thanks BTW i do this via the last strategy that you explained (creating new obj and setting it via setValue) I just thought will it cause any difference if we do it by useRef
@@mathuradas4955 If you use a useRef then setting current on that will NOT cause a re-render. Which may be what you want. Only state changes force a re-render. And by that I mean useState/useReducer state.
It's been a while but I think Svelte works off of references. I've heard using destructive operators on Svelte (push, pop, shift, etc.) doesn't work, which makes me think it's running of referential identity.
Fair, I left that out because for managing basic state I don't think it's acceptable. You have to box primitives (e.g. String("username") instead of just "username") and nested arrays/objects are problematic. I like what Solid did. They have createSignal for the basics, and then a createStore that returns a proxy model. I would love it if React had a built in `useStore` that would be a proxy model.
Prior to that advertisement for Brilliant, I'm surprised Jack isn't good with Math, and sciences, I guess programming logic is different to such aspects. I mean, I kind of struggled absorbing the intermediate knowledge of this video alone.
I'm dyslexic, so spatial stuff, how things fit together, I get that because I can make it visual. But theoretical math just doesn't really work for me. That's where the way Brilliant teaches math really helps because I can "play' with the equation and turn these equations into something I can visualize.
Mutable state: You have a desk with laptop, mouse, monitor and cellphone. Suddenly, your mouse drops on floor. So you take the mouse, and put it back to desk. Immutable state: You have a desk with laptop, mouse, monitor and cellphone. Suddenly, your mouse drops on floor. So, you go to the furniture store to buy exacly the same desk you have, then exaclty te same laptop, monitor, mouse. You go back to your office with all that stuff, kick your old desk with all of its content out of room, place newly purchased desk with laptop, monitor, mouse and cellphone on proper places. Then you call to the transport company to go and take your old desk & rest of old stuff. This is what "immutability" does to performance. Tons of mobile batteries drained on unoptimized websites, but at least we are modern and fancy.
React.createElement allocates a new object for each tag or component reference in your component. That means every time the app is re-rendered the entire VDOM tree is re-allocated. th-cam.com/users/shortsY7oS9Evn_2o A new state object getting created with a shallow copy in response to a user event is trivial in comparison to all the allocation being done to render a page with a lot of tags. (And that doesn't even count all the other function references, etc. that are created during a render.)
@@jherr indeed. I'm working on web app where performance is very important and I'm fighting a lot to make it performant. We use Vue, but it shares the problem with rerendering. During load time, after hydration, I've got a 40-50ms pause just due to GC cycle on desktop. This is the bad side of functional programming and I think at least frameworks should go towards performant code instead of "beautiful" code with no mutations. FP & Immutability is very nice tool, but do we have to use it ALWAYS and EVERYWHERE, even in framework internals, just to be modern and fancy? Like, should Vue or React really rerender huge parts of virtual DOM, which is at least O(n), instead of patching just what needs to be patched which can go down as low as O(1) in many cases (svelte does this afair)?
I'm honestly surprised anyone would consider anything else besides going with what React leans towards. Immutability is a fantastic principle to adhere to. Comparing references is ALWAYS going to be faster. Its like you said at the end, comparing values of objects is just always going to be far slower, and depending on the size of the object and where the value change is possibly nested, it can be even slower than this.
If React made the right choice, why every framework ( vue3, qwik, solid, svelte, preact, angular ) has acknowledged that modern uses of vdom and signals no only gives better DX and fine grained reactivity but also every single one of them is more performant out the box. If we go further than a todo list, you constantly need to evaluate react code to manually improve its performance. Its really tiresome how React devs keep pushing narratives to justify the dreadful dx until you internalize every pitfal in the model to solve the problems it gives.
Not always, there are cases when react can take significant time to render when you have a lot of components, or even when people don't understand how react works. I've been able to crash a web page by simply holding down a key on my keyboard, because everything on the page was updating when entering text. From my experience, react is great until a certain point. It can be a bit harder to maintain performance as many people are making changes in a team, and 1 line of code can ruin the performance of the entire page / sub tree. I feel like a lot of frameworks have been working towards making the mental model easier. I'm interested to see what the react team does in the future.
@@kr30000 If a single text change event causes the entire tree to re-render that's either an issue with the structure of the application, or an issue with the lack of a debounce. I don't see how that would be helped by picking a different state management model.
@@kr30000 true. But that kinds of mistakes can happen regardless of the library/framework. Anybody can write bad JS code. If it's easier to make mistakes in react, then I agree that it's a problem but my point is, if you code well, you don't need to worry about how performant react is as a UI library. If you want move to Solid because you think react is slow because of it's state management system, I'd say that's a very bad decision.
:) structuredClone, weirdly, turns out to be a lot slower than Lodash's deepClone. And I don't know and other JS native version of a isEqual outside equating two JSON.stringify's. What would you recommend instead?
Not sure if this is about the comment I left the other day or not. I just wanted to clarify I was addressing the internals of the framework, particularly why React requires developers to overwrite state (recreate objects and arrays) when we already make state setter calls which itself can be used alone to signal change and rerender the component. And it is the fact that Flutter is another reactive UI framework similar to React but doesn't have this requirement that made me pose that question.
It's not about any comment in particular comment, more about the ongoing confusion around referential identity based state change detection and the performance impact of creating new objects and the spread operator in particular. The intention was to show that show the complexity and performance impact of other approaches. You are correct that a decent argument could be made that we could forego the performance optimization of ignoring updates that set the same state value (or reference) and just always update instead. But if it weren't there I think folks would complain in the opposite direction.
@@jherr I see, but now that I think about it even more, I don't think the latter is an optimization since a) referential equality* does not imply equality by any means and b) it could be costlier from a memory management stand point (though, benchmarks that compare the cost of a component re-render to that of re-creating objects / arrays would be needed).
@@parlor3115 Not defending the approach (I'm not an FP-guy per se) but as to (a), in an FP model (which hooks certainly are) a change in reference certainly indicates a change since FP never mutates data in-place.
I despise services like "Brilliant." Not because they are lousy, but because of their pathological business model in which trying out so-called trial requires credit card details.... It is shameful to recommend such crap.
Impressive, very nice. Let's see Paul Allen's state management.
Why isn't it possible? Why not you stupid framework?
It's something called sillian toolkit
Your compliment was sufficient Luis
@@thedishwasherakawomen8878 that is actually a great name for a state management tool lol
any links?
I love these intermediate-level videos. So much content is aimed towards beginners and the advanced content gets complex real fast. This strikes aa nice balance
As always, you make those deep dives feel a lot more digestible and intuitive. Thanks!
To try everything Brilliant has to offer-free-for a full 30 days, visit brilliant.org/JackHerrington/. The first 200 of you will get 20% off Brilliant’s annual premium subscription.
Great video as always Jack, thank you! Interested in more of such intermediate topics which focus on inner workings of React and other libraries, and how it effects performance and developer experience etc.
I can never get enough of your videos, i already knew most of this stuff but you explained it like it was nothing Jack 🤝🏼
The first is somewhat similar to the vue3 proxy responsive principle, the second can use structureClone, the third point if you prefer to directly modify the mental model you can use immerjs
Never been disappointed watching your videos, Jack.. been over two years I think, every video I have watched, I have learnt a thing or two.. am so grateful to you..
I've been thinking about this recently, thank you for the informative explanation. It was an awesome video. I look forward to more videos delving into the intricacies of the subject.
It's been a while since I've doing one of these more "theoretical" videos. It was fun to do. But it's always a crap shoot as to whether it's going to perform well.
I heard vue 2 uses proxies and we had these issues with setting nested values.
Now i understand clearer
This was a treat. Thanks for the content.
To the viewers : don’t build your own state manager.
Valtio provides an amazing High Performance proxy state manager that is super simple to use properly: th-cam.com/video/gGY9HvUe2AA/w-d-xo.html
Agreed on not building your own.
fantastic comparison, good to learn about deep copy too using lodash
Damn, I learn something new everytime I watch your videos. Thanks Boss👍
Awesome thanks Jack!
I dont know how you come up with this ideas but... keep going. please. At the beginning I though that this video was more oriented to the 3 state management paradigms (proxies, atoms and flux) but was a surprise how it ended up!
I use valtio extensively and love it tbh.
I honestly prefer React's immutable approach. I like to treat every object as Object.freeze( ), so mutating some object directly feels weird, even more so if I have to mutate it & then set it again.
Very interesting as usual. Thanks.
Just migrated huge app state to Valtio yesterday from zustand. Initially I liked the idea of mutating data right away when needed, instead of defining setters, but soon started having issues with deeply nested arrays and objects. Migrating back to Zustand now 😥
I kinda like proxies, nested proxies are cached as well, so they only get created once, when accessed first, and it should be pretty fast; if we want to update properties that are nested 7 levels deep into a state inside a component I'd say we have bigger problems.
An alternative to the [state, setState] separation that would still work with primitives would be to consume a value like we do now with `state` and set it with `set.state({ thing: { to: "patch" }}), but setState isn't at all bad the way it is.
That was a great video. So interesting ❤
I love lodash and yes it's slower but I had to use it (deepCopy) on an incoming data stream from an ECG with an incoming sample every 2ms and it kept up pretty well. Anyways, I use both lodash and object-path in most of my projects for dealing with deeply nested objects
Rambda is a lot faster alternative. Clone (deep copy) there is 86% faster than in lodash.
@@twothreeoneoneseventwoonefour5 I'll give it a try thx for the tip
Just dont
Brilliant video
I'm Brazilian and have difficulty keeping up when the explanation is very fast. I enjoy your videos, but it's hard to understand. It would be amazing to watch videos with a slower pace for non-native speakers. tks
You can slow the playback speed down.
Oh my favorite channel on youtube.🌹
is the cloneDeep function to deeply copy a javascript object? If so, why not use structuredClone web API?
Nice thing about proxies is no stale closures in useCallback
Cases 2 and 3 are in the wrong order 0:57
At 16:38 you said the comparison would be true, but I think it would be false, please explain
Correct, just a slip of the tongue there. That would always be false.
Hi, Does react compare the mutable statetypes for rerendering, in the addAndCompareReference comparing two objects using "===" operator is a bit issue too i assume.
It actually uses Object.is, but === is the same behavior. It compares references and NOT contents. React itself does NOT care about the contents of your arrays or objects when it comes to state management.
I didnt even know that something like a "new Proxy" exists in JS... And I'm a intermediate dev. Seems like no one is talking about this, lol
maybe it's because i'm into functional programming only, but it seems like more usable in OOP
Hmmm, I'm actually not sure what the FP take on proxies is... Yeah. Probably a no-no. You're right. Side effects and all that.
It's a very useful tool
Good explanation.
As i rember Vue2 uses proxymethod?
Under which category do signals fall under? Been using them lately with Solid, and they just feel and run awesomely
I think they are by reference in Solid-JS. I'd have to confirm that. I doubt Ryan would make deep copies. He's too performance minded for that.
@@jherrSignals are by reference, Stores are proxies. And I guess the performance gain is probably more from explicit changes in the reactivity model instead of React just doing everything again because something, somewhere changed
very much helpful content👏
I think people doesnt give enough credit to hookstate, where do you stand on this Jack? It uses proxy and if you use it with useHookstate hook, you can observe nested objects with class getters and setters. Thanks for the great videos by the way.
Tried it a while ago and it was fine. Haven't tried it since.
I am wondering how to perfect the data structure of todoist like app.
Currently, using supabase I make simple query for project that has sections array, and each section has an array of tasks
I also use dnd-kit and I want to achieve the most performant task section change I can make.
Currently I keep my project obj in state, when I move my task I use structuredClone and change tasks order and section in this nested messy spaghetti.
Todoist uses flat projects, sections, tasks structure, each is a Map
Im trying different ways right now and flat arrays and nested arrays have similar results, (0.1 to 0.4ms task drag between sections) I'll try with maps, very fun to work with it
I know you are talking about something else, but you hint at something.
DeepCopy from lodash is something like the following
obj is of type obj, array, an array of objects, object of arrays, whatever
clonedObj1 = JSON.parse(JSON.stringfy(obj))
clonedObj2 = structuredClone(obj)
StructuredClone, which is native clone, is oddly less performant than deepClone. Super weird, but that's currently the case at least with V8. I just tested a JSON.stringify/JSON.parse variant and it's about 2.5X slower than the lodash deepClone/isEqual.
Think that is what I saw when doing my test also. I believe the StructructuredClone is not as defined as some other basic JS, meaning it could be very different per browser. stringfy/parse has the issue js has with strings and might be like regex under the hood.
Was thinking more just when you need the initial obj to be the obj, but are not using lodash in your project. Then you do initialObj.something.deep === newObj.something.deep. Maybe you need the initial Object for different parts of the code also, so not just comparing newObj vs initialObj.
Am I loosing performance when using valtio or mobx compared to other options?
No, actually MobX is one of the fastest state managers out there.
This is amazing!
Why not use immer instead?
I have been using deepsignal (the one where u can just mutate, there are two packages called that...) for the past two weeks and really like it. Is a proxy state built on top of preact/signals.
Question: What code theme are you using? It looks amazing!
Night Wolf [black]
What about the proxy performance?
I didn't run the benchmarks on proxies because I don't think they make a good option for basic state management. Primitive values need to be boxed (e.g. String("hello") vs just "hello"), which nobody is going to want to do, and nested objects and arrays get tricky because you have to mark them as proxied which means setting a special key, which messes up data integrity. It's just nasty.
One good alternative would be what Solid-JS does which is to have reference based state management with createSignal, and proxy based state management with createStore. It would be great if React had a built-in useStore.
It takes many many many geniuses to create Brilliant!
Immer is also based on a deep copy proxy? Is it as slow as your solution?
I'm not sure it is, as I recall it's kind of a hybrid proxy/deepcopy. It would be fun to try it out... :)
Amazing video 🎉
This made me curious about immer, since I’ve used it for some things, especially with deep objects (and the fact that the object destructuring gets messy in my opinion), and wow, three times slower than deep copy!
IMHO, the best thing to do is to learn how to manage object/array references.
I was curious same think and test them,
reference compare = 0.504μs
deepcopy compare = 5.859μs
immer compare = 9.986μs
Immer looks impressive, but only for DX
However, I'm concerned about its 20 times slower performance compared to reference. Is it worth sacrificing performance for this DX benefits? Btw, immer also has almost 5kb gzip package size.
what is this vscode theme, I love it so much
Night Wolf [black]
@@jherr thank you ❤
Jack: "I hereby promote you to platform architect" Me: 😨
Now I understand, why Non-primitive data are compared by their reference instead of their value in javascript 😊
Hi, nowadays no need loadash to create deep copy, all browser ( this is not part js) you can use structuredClone global fn- Of course in your test this fn will not work, you have to run in browser env.
Either way, i dont think that will change the conclusion.
Is slower then deepClone
@@bigmistqke did you tested? i always prefer native feature than external libs.
And depends on the browser, if you are using safari or FF ya maybe but in chromium base browser is a stretch.
@@jediampm yes i tested it myself, on firefox and chrome bc I wanted to get rid of lodash in website I m working on. It's substantially slower. google it if u don't believe me, it's actually quite established.
Can you make a comparison with signals too?
Not in React, no. Not without just a bunch of hackery.
@@jherr maybe in preact?
@@gordonfreimann Yeah, the preact signals are equally hacky. Any Solid-style signals on a VDOM framework is going to be subverting the framework because you are altering the DOM directly without the VDOM being updated.
What if we directly use useRef and mutate ref.current?
It will be something like signals
@jack can you help with this one?
Thanks in advance :)
If you are doing what I think you are doing then you're just subverting React and you should use Solid-JS instead. Solid was designed to do that from scratch. TBH, for most applications React performance is fine. It's freaky to see that a component function gets re-run when state changes, but in reality, that's very fast since it's just creating some objects which are compared against other objects and when there is a delta the DOM is updated.
By using useRef and then changing properties/attributes/content that React would normally do for you, you are just breaking React. And it's not clear why you would pay the price for the download of the React library just to subvert it.
Got it
Thanks
BTW i do this via the last strategy that you explained (creating new obj and setting it via setValue)
I just thought will it cause any difference if we do it by useRef
@@mathuradas4955 If you use a useRef then setting current on that will NOT cause a re-render. Which may be what you want. Only state changes force a re-render. And by that I mean useState/useReducer state.
How does Svelte do it? it's compiled to simple js afterall. is Svelte slower? No?
It's been a while but I think Svelte works off of references. I've heard using destructive operators on Svelte (push, pop, shift, etc.) doesn't work, which makes me think it's running of referential identity.
Signals signals signals
15:50 "Faker faker faker" 😂
But there was no proxy comparison...
Fair, I left that out because for managing basic state I don't think it's acceptable. You have to box primitives (e.g. String("username") instead of just "username") and nested arrays/objects are problematic. I like what Solid did. They have createSignal for the basics, and then a createStore that returns a proxy model. I would love it if React had a built in `useStore` that would be a proxy model.
Prior to that advertisement for Brilliant, I'm surprised Jack isn't good with Math, and sciences, I guess programming logic is different to such aspects. I mean, I kind of struggled absorbing the intermediate knowledge of this video alone.
I'm dyslexic, so spatial stuff, how things fit together, I get that because I can make it visual. But theoretical math just doesn't really work for me. That's where the way Brilliant teaches math really helps because I can "play' with the equation and turn these equations into something I can visualize.
Mutable state: You have a desk with laptop, mouse, monitor and cellphone. Suddenly, your mouse drops on floor. So you take the mouse, and put it back to desk.
Immutable state: You have a desk with laptop, mouse, monitor and cellphone. Suddenly, your mouse drops on floor. So, you go to the furniture store to buy exacly the same desk you have, then exaclty te same laptop, monitor, mouse. You go back to your office with all that stuff, kick your old desk with all of its content out of room, place newly purchased desk with laptop, monitor, mouse and cellphone on proper places. Then you call to the transport company to go and take your old desk & rest of old stuff.
This is what "immutability" does to performance. Tons of mobile batteries drained on unoptimized websites, but at least we are modern and fancy.
React.createElement allocates a new object for each tag or component reference in your component. That means every time the app is re-rendered the entire VDOM tree is re-allocated. th-cam.com/users/shortsY7oS9Evn_2o A new state object getting created with a shallow copy in response to a user event is trivial in comparison to all the allocation being done to render a page with a lot of tags. (And that doesn't even count all the other function references, etc. that are created during a render.)
@@jherr indeed. I'm working on web app where performance is very important and I'm fighting a lot to make it performant. We use Vue, but it shares the problem with rerendering. During load time, after hydration, I've got a 40-50ms pause just due to GC cycle on desktop.
This is the bad side of functional programming and I think at least frameworks should go towards performant code instead of "beautiful" code with no mutations. FP & Immutability is very nice tool, but do we have to use it ALWAYS and EVERYWHERE, even in framework internals, just to be modern and fancy? Like, should Vue or React really rerender huge parts of virtual DOM, which is at least O(n), instead of patching just what needs to be patched which can go down as low as O(1) in many cases (svelte does this afair)?
I'm honestly surprised anyone would consider anything else besides going with what React leans towards. Immutability is a fantastic principle to adhere to. Comparing references is ALWAYS going to be faster. Its like you said at the end, comparing values of objects is just always going to be far slower, and depending on the size of the object and where the value change is possibly nested, it can be even slower than this.
Because React is so boring and old
If React made the right choice, why every framework ( vue3, qwik, solid, svelte, preact, angular ) has acknowledged that modern uses of vdom and signals no only gives better DX and fine grained reactivity but also every single one of them is more performant out the box. If we go further than a todo list, you constantly need to evaluate react code to manually improve its performance. Its really tiresome how React devs keep pushing narratives to justify the dreadful dx until you internalize every pitfal in the model to solve the problems it gives.
jesus christ you are a beast jack
Awesome :)
The React you wan't is not 10x slower. It's actually faster and its called Valtio state library.
Lot of love for Valtio today! I love it!
If you worried about performance related to react's system of state management, you're worried about the WRONG thing.
1,000%
Not always, there are cases when react can take significant time to render when you have a lot of components, or even when people don't understand how react works.
I've been able to crash a web page by simply holding down a key on my keyboard, because everything on the page was updating when entering text.
From my experience, react is great until a certain point. It can be a bit harder to maintain performance as many people are making changes in a team, and 1 line of code can ruin the performance of the entire page / sub tree. I feel like a lot of frameworks have been working towards making the mental model easier. I'm interested to see what the react team does in the future.
@@kr30000 If a single text change event causes the entire tree to re-render that's either an issue with the structure of the application, or an issue with the lack of a debounce. I don't see how that would be helped by picking a different state management model.
@@kr30000 true. But that kinds of mistakes can happen regardless of the library/framework. Anybody can write bad JS code. If it's easier to make mistakes in react, then I agree that it's a problem but my point is, if you code well, you don't need to worry about how performant react is as a UI library. If you want move to Solid because you think react is slow because of it's state management system, I'd say that's a very bad decision.
@@kr30000 lol that example sounds like terrible design and architecture in your react project
It is going above the head 😂😂
Yeah, this is an intermediate to advanced video. But hey, just chill out, have a watch, should be reasonably entertaining at least. :)
@@jherr no doubt you are a great teacher.. Learned a lot of things from you.
Respect from Pakistan ❤️❤️❤️.
The React I want is Vue 😅
Wish I could modernize my old legacy React app over to Vue
3:47 why do the less readable Reflect.get(…arguments) when you can literally do obj[key]
Just use apollo client to cache everything and make that the source of truth
Lodash? What is this? 2015?
:) structuredClone, weirdly, turns out to be a lot slower than Lodash's deepClone. And I don't know and other JS native version of a isEqual outside equating two JSON.stringify's. What would you recommend instead?
Not sure if this is about the comment I left the other day or not. I just wanted to clarify I was addressing the internals of the framework, particularly why React requires developers to overwrite state (recreate objects and arrays) when we already make state setter calls which itself can be used alone to signal change and rerender the component. And it is the fact that Flutter is another reactive UI framework similar to React but doesn't have this requirement that made me pose that question.
It's not about any comment in particular comment, more about the ongoing confusion around referential identity based state change detection and the performance impact of creating new objects and the spread operator in particular. The intention was to show that show the complexity and performance impact of other approaches.
You are correct that a decent argument could be made that we could forego the performance optimization of ignoring updates that set the same state value (or reference) and just always update instead. But if it weren't there I think folks would complain in the opposite direction.
@@jherr I see, but now that I think about it even more, I don't think the latter is an optimization since a) referential equality* does not imply equality by any means and b) it could be costlier from a memory management stand point (though, benchmarks that compare the cost of a component re-render to that of re-creating objects / arrays would be needed).
@@parlor3115 Not defending the approach (I'm not an FP-guy per se) but as to (a), in an FP model (which hooks certainly are) a change in reference certainly indicates a change since FP never mutates data in-place.
@@jherr I meant referential equality and it doesn't imply value equality for non-primitive types.
@@parlor3115 Very true, at the most basic level it does not.
❤
No it’s not, Svelte is way faster 😂 And doesn’t have all of the bad abstractions and convoluted APIs
I despise services like "Brilliant." Not because they are lousy, but because of their pathological business model in which trying out so-called trial requires credit card details....
It is shameful to recommend such crap.
The React You Want is Svelte
make react series from scratch 2023 edition
Would you pay for it?
nope
@@mohitchandola3435 Fair enough.
@@jherr 🤦
this why javascript is so dumb. react has to create shit ton of objects just so they can diff easily... that's the biggest slow-down you can create..
JavaScript isn't just React, if you want an example for how to do a React style view framework without a ton of allocations check out Solid-JS.
When you're making "todo-like" apps and say that React is slow : D