The correct way to optimise React

Поделиться
HTML-код
  • Опубликовано: 19 сен 2023
  • Join The Discord! → discord.cosdensolutions.io
    VSCode Theme | Font → Material Theme Darker | Menlo
    It's finally time we talk about the correct way to optimise React. I see a lot of developers using React hooks like useMemo and useCallback wrong, and actually trying to over-engineer performance. This can even lead to, ironically, worse performance than you had to begin with! I show some examples here to hopefully clear this up once and for all, so that we can all go back to building performant React applications.

Комментарии • 66

  • @rmnkot
    @rmnkot 8 месяцев назад +57

    Let's don't forget about one important thing. React will re-render child component anyway regardless of wrapping variables or functions in hooks on parent render unless you wrap it in memo HOC. This concept is skipping in most of the videos like this which forms wrong mindset around this problem.

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +7

      Yes, made a comment in the vid I forgot to add it! But definitely!!

    • @miraclenerdkidchiki6249
      @miraclenerdkidchiki6249 8 месяцев назад +4

      So true bro....i always try to keep state local so as to prevent the parent from unnecessarily re-rendering and consequently the children. Basically, if its not needed elsewher, keep it local.

    • @federico9505
      @federico9505 8 месяцев назад

      ​@@miraclenerdkidchiki6249how do you keep it local?

    • @ZelarKyton
      @ZelarKyton 8 месяцев назад

      useMemo for expensive computation
      memo for preventing diffing a lot of markup unnecessarily when parent component re-renders, especially in loops
      useCallback for avoiding breaking children's memos when you need to pass callbacks to children with good amount of markup
      The saddest situation is probably when you need to close on some props and state in parent component's "action" callback, and pass that to the mapped children. One of the ways to fix it is this hacky hook:
      export const useEvent = Any>(cb: T): T => {
      const ref = useRef({
      cb,
      wrapper: (...args: Any[]) => ref.current.cb(...args),
      });
      useLayoutEffect(() => {
      ref.current.cb = cb;
      });
      return ref.current.wrapper as T;
      };
      This will have a stable reference and always fresh underlying callback. The only downside is that underlying callback and values it closed on will be one render behind latest if called from `useLayoutEffect` in child components, since child components run their effects first.
      Something like SolidJS would do granular updates for you, no matter where you put the state, but in react you need to think where to put state and how to split components to keep state-inflicted re-render cheap.

    • @MrEnsiferum77
      @MrEnsiferum77 8 месяцев назад +2

      Not if they are send as props, tree it's split then...

  • @KoOcie92
    @KoOcie92 8 месяцев назад +8

    @vishwasrv Correct sir, primitives such as strings, numbers or booleans are compared to each other by their value, where arrays, functions or objects are compared by their reference in memory. In other words on each re-render non-primitives are having a new reference, therefore using them in dependency arrays is just counter-productive. This is actually the most common mistake made even by the senior devs. That being said it is worth to mention that states in react if not changed directly, preserves their reference... which just introduce more confusions...

  • @CoericK
    @CoericK 17 дней назад +1

    What about wrapping the UserStats component with a React.memo(UserStats) ? What that be low performant as well?

  • @pedR
    @pedR 5 месяцев назад +1

    Once again great video!!! How can we evaluate the cost performance of each aproach? It would be interesting to do a video with metrics?

  • @soundsoflife808
    @soundsoflife808 5 месяцев назад

    Extremely useful content as always!

  • @deepakkashyap6538
    @deepakkashyap6538 8 месяцев назад

    Awesome explanation 🔥

  • @vishwasrv
    @vishwasrv 8 месяцев назад +3

    I have a doubt sir , passing objects as dependancy array in usememo or callback will always create new instances isnt it? In that case its better to use primitive values within the objects as dependencies, please correct me if I'm wrong?

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +1

      in theory yes, but here we're passing state, which doesn't get re-created. Even if state is an object

    • @vishwasrv
      @vishwasrv 8 месяцев назад

      @@cosdensolutions oh okay thanks sir will keep this in mind , so if it's an object from a parent passed down as a prop , then it would make sense to pass the primitive values I suppose

  • @pororit
    @pororit 17 дней назад

    its so good point for optimisation! thanks!

  • @coder5877
    @coder5877 8 месяцев назад +3

    It’s seem logical to think that useMemo and useCallback is not cost less and perhaps we should be using it more sparingly. But another thought that came to mine was the presentation given on the React compiler that meta is working where useMemo and useCallback is applied by the framework itself. In that case I’m wondering on what basis it will apply the optimization or if they feel like the cost is negligible and apply it across the board.

    • @miraclenerdkidchiki6249
      @miraclenerdkidchiki6249 8 месяцев назад

      I also heard of that new upcoming algorithm where React can automatically optimize certain components...but i believe its still in the works and has not been released yet

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +1

      can you link to that presentation? I've heard about this but never actually seen something concrete

  • @supersaiyan2
    @supersaiyan2 8 месяцев назад

    I am new to react, but if user is a state, wont user stats automatically get updated when user is changed? Whats the point of a useMemo?

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад

      yes it would, the point of useMemo here was to stop userStats from getting re-created if anything else than user changes. Ideally you only want it to change from user, not from anything else that might come up in the component. Usememo fixes that

  • @HarshShah465
    @HarshShah465 3 месяца назад

    Can you please create video on how to measure how many time rerender happens on clicking or any event?

  • @pavelisel4127
    @pavelisel4127 8 месяцев назад +3

    I'm still waiting for someone to give an example of an expensive computation, everyone says is for that but no one has ever given an example 😥

  • @asadmalik5075
    @asadmalik5075 8 месяцев назад

    Useful Man

  • @PwrXenon
    @PwrXenon 8 месяцев назад +4

    Greatest way to optimize it is to remove it entirely from your project

  • @user-ut4hj7kc1t
    @user-ut4hj7kc1t 2 месяца назад

    What make expensive calculations being expensive? Where it starts? Where is the border?

  • @balduin_b4334
    @balduin_b4334 8 месяцев назад

    whouldnt be the best optimization to use 2 variables instead of one obj?

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад

      that would make no difference in terms of performance here. It would only be better or worse depending on the project and how it's structured!

    • @Glinkis
      @Glinkis 8 месяцев назад +2

      Accessing properties of an object will always be slower then accessing variables. Objects are also worse for the garbage collector since they have to be allocated and in memory, in edition to the values that they store.
      But keep in mind these things don't matter unless you have a lot of them, or is accessing them in a very tight loop.

    • @balduin_b4334
      @balduin_b4334 8 месяцев назад

      @@Glinkis^

  • @garikmelqonyan6011
    @garikmelqonyan6011 8 месяцев назад

    Good tutorial

  • @isaacjon
    @isaacjon 8 месяцев назад +1

    I have an idea. imagine we have a page where at the top we have 3different filters and based on that we display an infinite number movies and also we have a search bar. You u need to make sure that everything is written like a senior developer to make this page the most optimized

  • @noherczeg
    @noherczeg 8 месяцев назад

    3:46, yes, but we are filling the garbage collector with dead weight. which could lead to longer gc periods.

  • @victorduarte4059
    @victorduarte4059 8 месяцев назад

    How can the performance be tested?

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +1

      you can measure it manually, or use the react dev tools profiler

  • @user-fr6gw8xr4b
    @user-fr6gw8xr4b 8 месяцев назад +1

    Isn't comparing to reference super fast. It is comparing two pointers. On another hand if the is object big and component rerenders a lot, the GC will not be very happy

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +1

      there is a cost, not 100% sure how deep it is, but it's always better to do things by necessity to avoid any overhead

  • @nonnnth
    @nonnnth 8 месяцев назад +2

    This looks unnecessarily complicated. Can I just useSvelte or other frameworks instead.

  • @wlockuz4467
    @wlockuz4467 8 месяцев назад +1

    Being highly nitpicky here, but this is still not optimized because its still creating and destroying an object on each render.
    If you really care about small performance gains then you should write a utility function outside of the component for both cases.

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад

      I think worrying about that kind of thing isn't worth it tbh. The idea of this video was how to use useMemo and useCallback properly, because those are bigger issues than the creation of objects and what not

  • @erezmizrahi1631
    @erezmizrahi1631 8 месяцев назад

    its meaningless If you use an object in the dependency array of useMemo.. the object will always have a new reference when the component re renders

  • @mcdaddy1334
    @mcdaddy1334 8 месяцев назад

    0:27
    ONE PIECE

  • @archmad
    @archmad 8 месяцев назад

    make an object as dependency is a red flag. That actually is the biggest sin

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад

      not really, you usually pass objects as props for example if you have a user, or a post, or a comment, etc. It's a very common pattern

    • @archmad
      @archmad 8 месяцев назад

      @@cosdensolutions you need to check how it is doing the comparison. it is always better to use primitive types than arrays/objects

    • @YasinAkimura
      @YasinAkimura 8 месяцев назад +1

      For a state object it is fine to pass it as dependency as it's easier comparing by reference once instead of comparing each member. If any value changed inside the user state object the reference will change anyways by definition of how react works.

    • @archmad
      @archmad 7 месяцев назад

      ​@@YasinAkimura that maybe true, but a good practice, please dont

  • @ranadenish
    @ranadenish 8 месяцев назад +3

    Sorry, but you can't just write your mistake in "Video Comment" directly.
    Someone might not read it correctly and will get bad concept.
    --- You might want to re-edit/re-shoot the video, but don't compromise quality.

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +2

      that's a fair point. I didn't have the opportunity to re-film this as I left for vacation the day after. For what it's worth, there is a visual comment inside the video saying my mistake, so some people should have seen it. I'll be more careful moving forward. Regardless, the rest of the video still applies and is valid, even with this mistake

  • @shaz101
    @shaz101 Месяц назад

    1000th like ❤

  • @MrREALball
    @MrREALball 8 месяцев назад +1

    The other use of useMemo, besides expensive operations, is if you need to have a more stable reference to an object.
    Also, you forgot that theres an additional cost for creating a callback function and a dependency array for useMemo.

  • @isaacjon
    @isaacjon 8 месяцев назад +2

    Bro make more practical stuff, this is too basic.❤❤

    • @cosdensolutions
      @cosdensolutions  8 месяцев назад +7

      Well not basic enough, I had to make the vid because a lot of people understood it wrong!

    • @iCodeArtisan
      @iCodeArtisan 14 дней назад

      Quite often it's these "basic" stuff that a lot of us miss.