‫It's time to shortly go back
‫to the WorldWise application in order to see
‫whether there are any performance issues
‫and whether there is anything that we need to optimize
‫in terms of wasted renders.
‫So here we are back in the WorldWise application,
‫and in case you had closed your editor before,
‫just make sure that you start both the fake API server
‫and the application again.
‫All right, and then let's come here to our application.
‫Let's just make sure to reload.
‫And so now I want to use the profiler here as well.
‫So just like we did previously in that other application.
‫And let's actually make this window a bit bigger
‫so that we can see exactly what's gonna happen here.
‫So what I want to do for now is just record
‫walking through the entire application
‫to check if there are any performance bottlenecks.
‫So to see if there is any component
‫that might perform really badly.
‫So let's start profiling, and then let's just follow
‫the flow of the application.
‫So we can go to all of these different components or pages,
‫and then of course we can log in.
‫We can click somewhere here, go back, click on a city,
‫maybe on the countries, maybe here, and then log out.
‫So just experimenting everything, and then let's finish.
‫And you see that we have a lot of renders.
‫So we created 21 renders in total.
‫And so let's now see if any of them was really slow.
‫So in order to identify some really
‫bad performing components, it's best to come here
‫to the ranked tab.
‫And so we see that the component that took the most time
‫in the first render was this route.
‫So that took less than one milliseconds,
‫which is really nothing.
‫So remember that in the previous app
‫when we were experimenting with the archive,
‫we sometimes had 200 milliseconds or 100 milliseconds.
‫And of course these values are different
‫on your computer than they are on mine.
‫Different, but still, this is like an order of magnitude
‫faster than what we had before.
‫So nothing to worry here, and so let's keep going.
‫So we just click here, and then we see
‫all the components that rendered and how fast.
‫So let's just quickly go through them
‫just to identify if anything was really slow.
‫So the most that we saw up until this point is this one,
‫two milliseconds, which again, is really nothing.
‫So it seems like in this application
‫we have absolutely no problem with performance,
‫which of course is very nice to see.
‫So let's just clean this, and maybe let's just analyze
‫one state's transition here.
‫So maybe here at this login part just to see a bit
‫what actually happens.
‫So just that navigation was actually four state updates.
‫So here in the flame graph we can see
‫that first the off provider was re-rendered,
‫which then made the login form
‫and all its children re-rendered.
‫Then, next up we saw that our router basically re-rendered.
‫So in order to move us to the next page.
‫So that's all of this stuff right here,
‫and of course you start seeing that once we add
‫all of these components to our tree,
‫it becomes all a bit more confusing.
‫All right, now what do we have here?
‫This is probably coming from the React Leaflet library.
‫So it's inside the map.
‫And then here we have some components
‫that are updating inside there.
‫And so yeah, these are related to positioning the map,
‫probably, and then finally we have another render,
‫which was caused by our router.
‫So that's what we can see here on the side.
‫So as we go through here, we can always see
‫what caused this update.
‫So here it was again the router,
‫and here it was the AuthProvider.
‫So because we logged the user in,
‫then the AuthProvider re-rendered,
‫which then triggered all of this.
‫Okay, and of course you can now analyze this a lot more
‫if you feel like, and if you want to have some fun
‫with this tool.
‫But for now, let's go back here to our code
‫to see what we can do.
‫And actually not a lot, as I was saying,
‫because everything is working really fluidly.
‫So earlier we were optimizing our context,
‫but even here there's not much to do.
‫Let's just delete this useState that we no longer need.
‫But yeah, so again, there's not a lot
‫to optimize here in this context.
‫So that's because we don't have any performance issues,
‫and also because the way that we set up our context value.
‫So remember how earlier we decided that we want to pass in
‫all of these functions into the context value,
‫and so therefore it wouldn't be practical
‫to create one separate context for each of them, right?
‫So that's one of the strategies that I mentioned earlier,
‫but that's not really practical and also not necessary here.
‫Also, there's not really a need to memorize
‫this value right here, because we don't have any component
‫above this provider in the component tree
‫that might re-render this one.
‫And so there's no point in doing that,
‫and so I think that there's actually nothing to do here,
‫which is good.
‫Now, let's just remember that there was some issue earlier.
‫And so we are now actually ready to fix that.
‫So if we come back here to our city,
‫remember that in the use effect,
‫we left out the getCity function.
‫So here we see that issue where eslint is telling us
‫to add the getCity, but remember that this created
‫an infinite loop of HTTP requests to our API.
‫But let's do that again now.
‫So getCity, then let's just reload here,
‫and maybe let's come actually to the network tab,
‫clean all of this, and then watch what happens
‫when I click on one of these cities.
‫And indeed, immediately we get like a thousand requests,
‫and it keeps going even though the number here
‫is not going up.
‫But we can also see down here that every second or so
‫there is a new request coming in.
‫And even here it's of course also very visible.
‫Now, we can even see the same in the profiler.
‫So if we go back and then start profiling clicking here,
‫and then I will just leave it for a few seconds.
‫That should be enough.
‫And you see that we have 60 state updates
‫only in this three seconds that I waited.
‫And so clearly there is something wrong here,
‫and this is the only thing that we need to fix now
‫using the tools that we learned before.
‫But first of all, of course, we need to understand
‫what is actually happening.
‫So now that we have this getCity function
‫in our dependency array, the effect will rerun
‫each time that it get city function gets updated,
‫or in other words, that it gets recreated.
‫Now, when does this function get recreated?
‫Well, since it lives in the context, so let's open that.
‫So this file, getCity, lives here,
‫so it is created in this city's provider.
‫But the problem is that this getCity function
‫will update the state each time that it is executed,
‫which will then end up in an infinite loop.
‫So here we call the getCity function, right?
‫And so that function will then update the state
‫in this component.
‫Then this component will re-render,
‫which will then recreate this function.
‫And as the function gets recreated,
‫since it is here in the dependency array,
‫then getCity will get called again,
‫which then again will update a state, which will re-render,
‫which will cause the effect to run over,
‫and over, and over again.
‫So that's the infinite loop that we have right here,
‫and probably we should come back here
‫and now take our application out of this misery.
‫So it's been fetching for a few minutes now,
‫so that's a bit too much.
‫But anyway, how do you think we can fix this?
‫So the solution is not to remove this
‫from the dependency array,
‫because that is not allowed in React.
‫Instead, what we need to do is to make this function stable.
‫So we need it to not be recreated on each re-render.
‫And the way we do that, as you hopefully know,
‫is by using the useCallback hook.
‫So let's create a new variable,
‫which will be the new getCity function,
‫and this will then be the result of calling useCallback.
‫All right, then our dependency array,
‫which will need probably this currentCity.
‫And there it is.
‫So currentCity.id, and once again,
‫just having this kind of warning here
‫is reason enough to really always install eslint
‫in your projects.
‫So without it, you'll create so many bugs,
‫it's not gonna be funny, really.
‫But anyway, this now shows you a real world use case
‫of this hook, so of this useCallback hook right here.
‫So this is one of these real world situations
‫in which you will really need to reach for this tool.
‫So that's why it's really important
‫that you paid good attention throughout this section.
‫And actually remember that when I first introduced
‫these hooks, this was exactly one of the three use cases
‫that I talked about.
‫So memorizing values that are used in the dependency array
‫of another hook in order to prevent infinite loops.
‫So let's give it a reload here,
‫and then let's just try it again.
‫And if we come here to our network tab,
‫then we see that there is no problem anymore.
‫And also here we are not seeing
‫these infinite requests coming in.
‫All right, and this is actually
‫all that I wanted to show you in this lecture.
‫And I can understand that it probably
‫seems pretty intimidating,
‫for example, to find out by yourself
‫that this would've been the solution here.
‫But trust me, that with practice and with study,
‫you will be able to really understand
‫and to master all these tools.