Тёмный

Is JavaScript Spread a Performance Killer? Quick Fix 

Jack Herrington
Подписаться 184 тыс.
Просмотров 42 тыс.
50% 1

Опубликовано:

 

8 сен 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 188   
@lynn_phoenix
@lynn_phoenix 2 года назад
For a real world improvement, this was the difference of a search endpoint taking 1100ms vs 200ms. The original developer preferred DX with expressive code over user affecting performance and it caused Core Web Vital issues.
@ZakiWasik
@ZakiWasik 2 года назад
This is really interesting. I've been doing spread destructuring simply out of habits acquired from using Redux. But I guess I have to rethink that when using reduce.
@HeinekenLasse
@HeinekenLasse 2 года назад
Wow I always thought that background was real haha
@jherr
@jherr 2 года назад
It is actually my office. I just use a plate that I shot at the day in summer, and so now I can use it in the dark of fall. ;)
@ddoice
@ddoice 2 года назад
This is why ended up using ramda, it allows you to keep the functional syntax with great performance. On a brute force code I needed all the permutations of combinations of words extracted from paragraphs (near 1.5M), the code using reduce will take 4 hours to calculate all, with ramda was 5 secs.
@henrmota
@henrmota 11 месяцев назад
Jack, I think it would be interesting to make a video on how to measure the performance of functions and how to measure that performance. Thanks for your videos.
@floofynuggets
@floofynuggets 2 года назад
This is a great tip, Jack! I've also implemented this in performance-sensitive situations. However, I don't always apply this advice because of the no-param-reassign eslint rule which I usually have enabled in my projects. This rule helps avoid mutating object references passed into a function. I think I'd add one point to Jack's video here: this performance-boosting trick has no downsides _because_ the lookup is initialized with {}, and not an existing object reference. If you're in this situation, only _then_ is it permissible to apply this approach and ignore the rule. Cheers!
@jherr
@jherr 2 года назад
Honestly, I never even think of initializing reduce with an existing reference.
@floofynuggets
@floofynuggets 2 года назад
@@jherr I don't blame ya! Neither do I. The lint rule just discourages me from consistently applying this tip and I thought I'd help explain it. Thanks again for your work making videos Jack.
@mammothoff
@mammothoff 2 года назад
I always destructture with spread, but now I'll think twice before using spread, thanks 👍🏻
@codezero6023
@codezero6023 2 года назад
Yes, I have gotten burned using an assign function in a reduce. The spread operator may seem more functional, but “mutating” the accumulator by setting the key is much more efficient.
@Kay8B
@Kay8B 2 года назад
This is amazing, More efficiency tips like this would be awesome short videos to share with friends.
@JulioDx3480
@JulioDx3480 2 года назад
I had no idea about this performance hit with destructuring. Thanks for sharing.
@cwinter90
@cwinter90 2 года назад
Didn't realize the performance was that bad between them lol. I believe I've always done the good version but that was more by luck than thinking about performance I think 🤣
@AbdelhameedG
@AbdelhameedG 2 года назад
Thanks Jack, That was enlighting, Would love to see more videos about performance from you.
@drewbird87
@drewbird87 2 года назад
I'm still calculating the amount of times I've done this using ...spread . 😳 Thanks Jack 👍🏼👍🏼
@mauriciabad
@mauriciabad 2 года назад
I would have done this: Object.fromEntries(people.map(person => [ person.id, person ])) I don't know how efficient it is, but it's very readable.
@jherr
@jherr 2 года назад
That's a good one, and it should be very efficient.
@AbdelhameedG
@AbdelhameedG 2 года назад
Nice idea
@Weagle1337
@Weagle1337 Год назад
Thank you Jack, I enjoyed this video at 1:00 AM eating an instant ramen
@sagarreddy7461
@sagarreddy7461 2 года назад
Awesome content jack, thanks. Waiting for your js objects details series
@purswanitarun
@purswanitarun 2 года назад
Your voice and way of explaining makes me want to get up early and always keep learning. Thank you :)
@ShaharHarshuv
@ShaharHarshuv Год назад
I think mutating the object you're creating still abides functional programming principles since you're not mutating the function arguments, so the function is still pure. I think it's ok that the reducer's callback is not pure since it's used once and in place
@Yutaro-Yoshii
@Yutaro-Yoshii Год назад
If you don't plan to consume the output right away, for loop is also a great option. const result = {}; for(let person of people){ result[person.id] = person; }
@mohammadmahdifarnia5358
@mohammadmahdifarnia5358 Год назад
Immutability kills performance & blows up memory. react-table had this issue (primegen has a video on this) Great video👍
@PeerReynders
@PeerReynders 2 года назад
Nitpick. Technically this isn't about destructuring assignment but the spread syntax being used to *create* object instances. Destructuring uses the rest syntax (which gathers properties rather than spreads) which looks exactly like the spread syntax. The spread syntax expresses is the opposite of the rest syntax used in destructuring.
@jherr
@jherr 2 года назад
You are correct and fixed in the title and description.
@Shahbaaz.28
@Shahbaaz.28 Год назад
Now I finally got something new on you tube Thank man
@DanielTateNZ
@DanielTateNZ 2 года назад
This answers the questions I had on your other reduce video. Thanks!
@karnellschultz6446
@karnellschultz6446 2 года назад
pretty good stuff. working on some performance issues right now and noticing these patters all over the place. Not sure if this is my silver bullet, buttt very good to keep in mind.
@FuzailShaikh
@FuzailShaikh 2 года назад
Thanks man, I’ll be more cognisant using spread operator now
@Sashankyt
@Sashankyt 2 года назад
I would have never done that spread but it was insightful. Thank You.
@stephanekiss
@stephanekiss Год назад
A spread inside a reduce is going to be a square complexity, not cube. There is one loop in the spread operator that has to copy every property of the lookup object into a new object, and the other is the reduce. Two nested loops = square.
@mostafaabobakr
@mostafaabobakr 2 года назад
THANK YOU applied this immediately
@_erfanm96
@_erfanm96 2 года назад
Right, but I didn't see anything about destructuring (the title) in the video. It was about the performance effect of using the spread operator for returning a new object on every iteration.
@jherr
@jherr 2 года назад
That is true.
@jrs_devs
@jrs_devs 2 года назад
Perfecto!, just corrected a couple of pieces of code with this smart fix. Thank you Jack!
@personalquests
@personalquests Год назад
For the second example i would have used the map function it eliminates the need to create a new array on every loop. The first example okay. thank you great tutorials. i do love them.
@helloworld_5
@helloworld_5 11 месяцев назад
this was a great video, thanks
@ivanjasenov1220
@ivanjasenov1220 2 года назад
Great point!
@collenzaligway4458
@collenzaligway4458 2 года назад
I love you content. Thanks for sharing your knowledge. Will share your video to my colleague so you can get more subscriber.
@evanfuture
@evanfuture 2 года назад
I wonder if there's an eslint rule for this. Because object spread is certainly preferred in my codebases to avoid mutations (and to help with change detection). It would be nice to highlight cases inside reduce methods only...
@saichand5752
@saichand5752 2 года назад
Very intresting... thanks for info
@ShingoSAP
@ShingoSAP 2 года назад
Awesome !! 👏👏👏 Thanks for Sharing ! 👍
@bigmistake5565
@bigmistake5565 2 года назад
3:40 are they semantically the same tho? Option A ur making a new object, option B ur mutating lookup. It's just that there is no danger in mutating, as lookup only exists within the scope of the reduce-function.
@jherr
@jherr 2 года назад
There is no semantic difference. You still get a new object or array either way. It’s just a question of how many objects are created and destroyed in the process of generating the result.
@samuelgunter
@samuelgunter 2 года назад
@big mistake with option 2, you're mutating the object that is passed in as the second argument {}
@ToJak91
@ToJak91 Год назад
Not only more performant. But it's easier to read aswell.
@maksym7279
@maksym7279 2 года назад
Thanks!
@pushpendra-sharma
@pushpendra-sharma 8 месяцев назад
Really helpful.
@views-qw9tf
@views-qw9tf 2 года назад
Thank you so much
@SmotritelTube
@SmotritelTube Год назад
I would like to see the best useThrottle function in react!
@adamlerman4173
@adamlerman4173 2 года назад
Thanks as always for a great video Jack!
@joonaskrohn6785
@joonaskrohn6785 2 месяца назад
I could have sworn that you once had a video comparing the performance of array copying with spread, for loop and other methods. Has it been deleted for some reason?
@jherr
@jherr 2 месяца назад
I haven't deleted many videos, and I certainly don't remember deleting a basic JS video like that. I've covered it a bunch of times though.
@reprisal0
@reprisal0 2 года назад
Is there a list of the extensions you use for VS Code?
@jherr
@jherr 2 года назад
This one is Quokka. But yeah, I'll be doing a video on that.
@KaizenCodes
@KaizenCodes 2 года назад
Great video Jack! Thank you!
@shubhamlatiyan7972
@shubhamlatiyan7972 2 года назад
Great information Jack, Thanks
@12px
@12px 2 года назад
Thanks sir!
@heguer87
@heguer87 2 года назад
Good to know!
@trenthm
@trenthm 2 года назад
Great video! Thanks!
@MrPlaiedes
@MrPlaiedes 2 года назад
No one should be surprised when polyfills cause a performance hit. That's part of the trade off, I think, for wanting a new feature without fully supporting it. Thx for the video!
@jherr
@jherr 2 года назад
Even without polyfills this is a performance hit, because for an array of N items, with a desired output of 1 object or array, you are creating N+1 interstitial objects or arrays, all with increasing size, and then discarding N of them.
@MrPlaiedes
@MrPlaiedes 2 года назад
@@jherr Sure. I suppose there are a lot of assumptions here, though. Older versions of JavaScript may be due to older browser (older computer? Maybe a corporate limitation?). I am also assuming if you can use spread operators, your system should be able handle what spread is doing under the hood. Hope you don't mind my comments. Thanks for your videos, Jack!
@jherr
@jherr 2 года назад
@@MrPlaiedes Don't mind the comments at all. Keep 'em coming. That being said, I ran the numbers for the performance on Node 16, which is handling the spread operator and those are the results I got. The issue really is the N+1 problem. You want 1 object (or array) and instead you are creating N+1 temporary objects (or arrays) and then throwing away N of those and keeping just the one. And each of those temporary objects (or arrays) is a complete copy of the previous one. So they get bigger and bigger and slower and slower as you go.
@ChrisAthanas
@ChrisAthanas 2 года назад
Very useful
@CrazyCodingChannel
@CrazyCodingChannel 2 года назад
Very intersting, thanks a lot
@aleksd286
@aleksd286 2 года назад
You made me cry because I tend to write in a functioning style
@laztheripper
@laztheripper 2 года назад
Isn't a for loop clearer and more performant? I mean besides the slick one-liners, what purpose do they serve that for loops don't?
@jherr
@jherr 2 года назад
If you use ++i a for loop is very slightly faster, but you still have a raft of possible bugs that you don't with for(of) and for(in). The traditional for loop is good when you need precise control of the looping constraints, if your intention is just to loop through every item us for(of) or for(in). Those make your intention clear,.
@technikhil314
@technikhil314 2 года назад
I am wondering why did you not use performance.now() And if my understanding is correct the reduce was made to make sure you can mutate the accumulator
@jherr
@jherr 2 года назад
Sloth and yes. :)
@vincentweber1359
@vincentweber1359 Год назад
That's also pretty nasty in terms of garbage collection. I know, the v8 scavenger doesn't have that much problems with objects that die pretty much immediately, but it's still something that might trigger a minor gc cycle early on, and I'd recommend avoiding that, especially during animations or game loops.
@Ivanandcode
@Ivanandcode 2 года назад
Nice explanation, thank you!
@jameshans7459
@jameshans7459 2 года назад
What is the name of the extension used for previewing the results?
@jherr
@jherr 2 года назад
Quokka.
@shinkobayashi5915
@shinkobayashi5915 2 года назад
Thank you! Thank you! very useful
@feyokorenhof
@feyokorenhof Год назад
Interesting. That is actually very helpful, thanks!
@darkmift
@darkmift 2 года назад
Coming across this I wonder. The spread reducer returns a new array but the other Returns the array passes by refrence into the accumulator. This may result in issues in some cases
@jherr
@jherr 2 года назад
Maybe, but I think if you understand references enough to use a form of reduce where you mutate the referenced object or array as opposed to continuously creating new objects or arrays, then you'd probably know to control the provenance of the original object or array.
@aksyonov100
@aksyonov100 2 года назад
I believe Ikea had that issue where you can't checkout 1000 items from the basket, site would be simply unresponsive. They have been losing money because of that simple mistake ;-)
@jherr
@jherr 2 года назад
Hahah, ok. BTW, thank you for the video idea. I forgot to mention you in there. But yeah, you are right, this is mostly something you are going to run into on the node side crunching bigger datasets.
@aksyonov100
@aksyonov100 2 года назад
@@jherr thanks to you for the channel! Learned a lot from your videos :-)
@Cowglow
@Cowglow 2 года назад
Lovely Video
@Skar38rus
@Skar38rus 2 года назад
nice tip, thank you Jack
@techsy7404
@techsy7404 2 года назад
I really love your content, I wanna learn the architecture thing of an application. Any recommendations or tutorials?
@sajedsoliman4780
@sajedsoliman4780 Год назад
Really useful one Thx ❤
@danhthanh418
@danhthanh418 2 года назад
Great content. Thank Jack
@shinmessiah
@shinmessiah 2 года назад
Good stuff sir, love this content
@arcosd63
@arcosd63 2 года назад
Hey, Jack, good show. May I ask how do you get the comparison performance chart on your screen?
@jherr
@jherr 2 года назад
That's After Effects. I use a couple of effects on it to swivel it, then do the animations.
@arcosd63
@arcosd63 2 года назад
Hey Jack, thank you for your prompt response. I am really enjoying the way you explain material, so I'm going to look into one of your courses.
@savolus
@savolus Год назад
using `new Map` with `hash.set(key, value)` may even be faster then using object like this
@ferrben8047
@ferrben8047 2 года назад
Love your content Jack!
@Petertumulty
@Petertumulty 2 года назад
Does this anti-pattern also apply to map? Would either of these be considered anti-patterns? const offices = officeLocations.map(({ id, title, address, phone, fax, slug }) => ({ id, title, address, phone, fax, slug })) or const offices = officeLocations.map((office) => ({ ...office }))
@jherr
@jherr 2 года назад
Map doesn't have the same unexpected behavior, because you are creating objects 1-to-1 to match the array. Where in these reduce examples you are creating a single object or array, and with each iteration it's getting bigger and bigger so the copies are more and more expensive as the array size grows.
@Petertumulty
@Petertumulty 2 года назад
@@jherr oooohhh i see, mind blown! Thank you
@sigmawolf228
@sigmawolf228 2 года назад
There's no such a thing as anti-pattern with Jack. He's a Senior HelloWorld Developer, what are you talking about?
@Stnaire
@Stnaire 9 месяцев назад
You're almost there. Now get rid of the reduce and do a simple loop. Using reduce is totally useless (at least in that case) and you got a function call for each item of the loop, which is slow.
@LukasPetry
@LukasPetry 2 года назад
Yes, of course. In this case totally on point, however be patient, in other scenarios mutating objects or arrays gets you into trouble. So I think it makes a lot of sense to default on spreading as this is more of a performance optimisation
@mirtanvirahmed3868
@mirtanvirahmed3868 2 года назад
which extention do you use to see real time results in the editor? Like when you put you cursor on a object, editor shows a result in the right side of that line??
@jherr
@jherr 2 года назад
Quokka: quokkajs.com/
@pierre-jeanmartin5621
@pierre-jeanmartin5621 2 года назад
Just look at the transformation priority premise: reassigning a new object is the worse transformation
@hypealex
@hypealex 2 года назад
What are you using that will output the result in file, that you dont need to do console log?
@jherr
@jherr 2 года назад
Quokka quokkajs.com/
@CarnivorousSpork
@CarnivorousSpork 2 года назад
Wondering if you could elaborate on the underlying aspects that make this slow in JS but performant in others like Scala?
@jherr
@jherr 2 года назад
In JavaScript, if you use this anti-pattern on N items you'll get N copies of the output object (or array) plus the one output object (or array) that you actually want. And each copy will be successively larger than the last. Scala has referential data structures so an array can say; "I'm just this array over here, but with this added value." So instead of having N arrays you are basically creating a linked list of related arrays. Still probably not as fast as simply mutating an object (or array), but that's probably mitigated by it being on the JVM and being compiled.
@xinaesthetic
@xinaesthetic 2 года назад
I made a similar comment a couple of minutes ago, so apologies if I’m repeating myself. It’d be interesting to compare to something ClojureScript or Elm that should be using similar data-structures in a JS context.
@user-ti1kc7qk3n
@user-ti1kc7qk3n Год назад
감사합니다. 제 코드에도 이런 문제가 많을 거 같아요.
@artemtarasenko9744
@artemtarasenko9744 2 года назад
So, essentially, do not return an object or an array from a loop, if you don't really want to create an additional instance of it every single iteration. That should be in the docs)
@jherr
@jherr 2 года назад
Yeah. Don't make JS building an object that you are probably just going to throw away. :)
@samucancld
@samucancld Год назад
Concerning, I always use spread
@TheZayzoo
@TheZayzoo Год назад
Does anyone know that add on for the preview in the blue text?
@victorlongon
@victorlongon 2 года назад
That makes sense but this is really only relevant if you have really big data. I mean for most people in most scenarios it will only be like some dozens of objects so maybe it is a good idea to keep the more readable code? But again it totally makes sense depending on the volume of data you are handling
@jherr
@jherr 2 года назад
Completely agree, I mentioned that at one point that the impact of this on the client would probably be nil because of the smaller data sizes. But if you're making a library, or you don't know the context or the potential maximum size of the data set, then this is something you should be aware of.
@supergoteam
@supergoteam 2 года назад
A single big data set is of course one way of getting there. But also think in terms of nested small datasets. Loops in loops can quickly that up that big O and bring optimisations like this back into focus.
@xinaesthetic
@xinaesthetic 2 года назад
If you’re in a situation where you care about GC pauses (games etc), that is another reason to be very mindful of unnecessary object allocations. Also, while there’s definitely some truth in it not always being necessary to think about scalability when you know your code only runs on small datasets, I think we have a lot more bloated and slow software than we need in the world and it’s ultimately contributing to data centres etc consuming a lot more energy and having a much higher carbon footprint than they should.
@victorlongon
@victorlongon 2 года назад
@@xinaesthetic for sure. I thought about writing stuff for games for instance and also in those cases maybe you don't even want immutability at all (in a lot of scenarios at least) ?
@supergoteam
@supergoteam 2 года назад
@@xinaesthetic Absolutely agree especially on the points of large scale wastages. We generally code with human first attitude but keeping an eye on easy optimisations where we can. Just because we can be lazy doesn't mean we should. On the flip side of that optimisations first is something we haven't 'had' to do for quite some time now and can really slow a project down. Like all things in life it is about finding a balance.
@OlDirtyLZA
@OlDirtyLZA 2 года назад
Question does this only apply to reduce method? I wonder would using the spread operator in a reducer cause any performance issues?
@jherr
@jherr 2 года назад
I can't think of any of commonly taught pattern that has this kind of performance issue. But I'll definitely have more of a think about it.
@dwakeling1
@dwakeling1 Год назад
I think you may have gotten the big O notations the wrong way around. From my tests its the object that is ^2 and the array is ^3
@mysuperemecy
@mysuperemecy 2 года назад
It was realy great learning, would you suggest any book which covers such anti patterns in good detail
@sfansari007
@sfansari007 2 года назад
This is amazing. I never thought that internally it may impact so much. What's the name of that extension which is showing the output on hover
@jherr
@jherr 2 года назад
Can you cite a time reference? I think it's just the usual hover.
@roberthaforsson9687
@roberthaforsson9687 8 месяцев назад
@@jherr It is on min 3:15. For me its not the usual hover
@jherr
@jherr 8 месяцев назад
@@roberthaforsson9687 That's Quokka. It's an extension.
@SeaRich
@SeaRich 2 года назад
React use that to update states a lot.
@Aspiiire
@Aspiiire 2 года назад
great video thank you :D
@Smileyassassin47c
@Smileyassassin47c Год назад
But they are used for different purposes. I don't feel like this is an apples to apples comparison(i mean it is technically but not when you think about the problem you're solving), you use spread when you specifically want to create new objects instead of using the references, such as when tracking state changes.
@saichand5752
@saichand5752 2 года назад
What's the extension you are using??
@jherr
@jherr 2 года назад
Quokka.
@chakhmanmohamed9436
@chakhmanmohamed9436 2 года назад
Mr. Jack i looooove your videos. I would love a course recommendation if you know any.
@hoads19
@hoads19 2 года назад
The benefits of the spread operator is immutable. Is the second method immutable?
@ukaszzbrozek6470
@ukaszzbrozek6470 2 года назад
You create one object and you mutate that. Original data isn't change. There is no down side to that mutation.
@jherr
@jherr 2 года назад
It is not immutable, but, let's think about what's happening here. You have a set of N elements from which you want to derive one object or array. And you can either create N+1 objects (or arrays) and throw away all of the N in the process, or you can create one. And in both cases you get a new object or array. Does the gain of having N temporary objects that you throw away that are immutable outweigh the benefit of using a mutable process to derive the one output? And with either process the resultant object (or array) is itself mutable (unless you freeze it).
@shunia
@shunia 2 года назад
The video is great and at the point, but it's still insane that only one comment mentioned this. If you have a really huge dataset and are trying to reduce it, it's mostly wrong at first place. You either take part of the data out of the dataset then edit, or you just use a more efficient way to store your data so it's performant to edit. And if you are doing something mutable to the original dataset, it could cause unwanted behavior in components which used the same dataset, because although the dataset contains the data didn't change, but the data itself has been changed.
@petrtcoi9398
@petrtcoi9398 Год назад
Great video. But why TS just don’t convert spread operator to “fast” version of code?
@jherr
@jherr Год назад
TS's core concept is that you should be able to strip the TypeScript annotations from the code and be able to run the JavaScript as-is. It doesn't make modifications to how your code works. It just checks types.
@petrtcoi9398
@petrtcoi9398 Год назад
@@jherr Sorry. Not correct answer. I mean Babel
@jherr
@jherr Год назад
@@petrtcoi9398 Ah, ok. It would have to understand the semantics of what you are doing. If you are doing a map then a spread is appropriate if you want to create a new object to replace every element in the array. I wouldn't trust any transpiler to make that call.
@petrtcoi9398
@petrtcoi9398 Год назад
@@jherr OK. I see. Thank you
@michallevy9806
@michallevy9806 2 года назад
So creating new object/array in every loop is slower than modifying the existing object/array? What a revelation :)
@chippycode
@chippycode 8 месяцев назад
Please, which plugin suggest the output at the end of the line?
@jherr
@jherr 8 месяцев назад
Quokka or Console Ninja.
@fredbluntstoned
@fredbluntstoned 2 года назад
So the fix is to not use the spread operator to create a return object in a loop if you can simply reuse an already created object?
@jherr
@jherr 2 года назад
Yes. Simple. But, unknown to some folks, so... a video. :)
@s3xta13
@s3xta13 2 года назад
@@jherr I believe that most are taken by the immutable lintings. At least in the FE world
@jherr
@jherr 2 года назад
@@s3xta13 Confused, are you saying that eslint would fix that for us?
@s3xta13
@s3xta13 2 года назад
@@jherr no no... But mainly most configurations for eslint shows a warning saying that a .push in an array is mutating value and probably isn't what you want. What I'm saying is that most of newcomers to js or react (for example) can be led into fixing a .push to the spreading option...
@jherr
@jherr 2 года назад
@@s3xta13 Ahhhh, gotcha, that would be unfortunate, because in this case you really want to use the much-maligned push.
@SanderRombouts
@SanderRombouts 2 года назад
How does the more optimized reduce compare to a for-loop or for-in-loop?
@jherr
@jherr 2 года назад
This is basically turning the reduce back into a for loop for all intents and purposes.
@SanderRombouts
@SanderRombouts 2 года назад
@@jherr Thanks! I'll do some performance test on large arrays myself. Curious at what array sizes the difference is going to be significant (enough). Enjoying your videos!
@jherr
@jherr 2 года назад
@@SanderRombouts Here is the code so you can try it out for yourself: github.com/jherr/javascript-quick-fixes/tree/main/destructuring-is-slow/performance-tests But it's pretty common sense, basically to create a single output object for N elements in an array we are creating N copies of the output array each larger than the previous copy and including all the previous data. Depends on your CPU but I was able to get significant slowdown at 100K elements for a single pass, or 100 * 1K elements in multiple iterations.
Далее
Code Splitting Made Simple
28:11
Просмотров 44 тыс.
How Slow Is JavaScript? | Prime Reacts
15:34
Просмотров 178 тыс.
Starman🫡
00:18
Просмотров 13 млн
You're Doing React Hooks Wrong, Probably
20:11
Просмотров 64 тыс.
Premature Optimization
12:39
Просмотров 803 тыс.
Node.js is a serious thing now… (2023)
8:18
Просмотров 644 тыс.
3 React Mistakes, 1 App Killer
14:00
Просмотров 115 тыс.
Mastering React Context: Do you NEED a state manager?
37:26
Why Signals Are Better Than React Hooks
16:30
Просмотров 474 тыс.
React 18's New State Hook You've Never Heard About
22:11
Blazingly Fast JavaScript with ThePrimeagen | Preview
18:22