﻿1
00:00:01,170 --> 00:00:03,330
‫It's time to shortly go back

2
00:00:03,330 --> 00:00:06,780
‫to the WorldWise application in order to see

3
00:00:06,780 --> 00:00:09,750
‫whether there are any performance issues

4
00:00:09,750 --> 00:00:13,260
‫and whether there is anything that we need to optimize

5
00:00:13,260 --> 00:00:15,573
‫in terms of wasted renders.

6
00:00:17,100 --> 00:00:20,820
‫So here we are back in the WorldWise application,

7
00:00:20,820 --> 00:00:24,090
‫and in case you had closed your editor before,

8
00:00:24,090 --> 00:00:28,200
‫just make sure that you start both the fake API server

9
00:00:28,200 --> 00:00:30,033
‫and the application again.

10
00:00:31,230 --> 00:00:35,220
‫All right, and then let's come here to our application.

11
00:00:35,220 --> 00:00:37,830
‫Let's just make sure to reload.

12
00:00:37,830 --> 00:00:42,750
‫And so now I want to use the profiler here as well.

13
00:00:42,750 --> 00:00:47,340
‫So just like we did previously in that other application.

14
00:00:47,340 --> 00:00:50,910
‫And let's actually make this window a bit bigger

15
00:00:50,910 --> 00:00:53,613
‫so that we can see exactly what's gonna happen here.

16
00:00:55,260 --> 00:00:57,870
‫So what I want to do for now is just record

17
00:00:57,870 --> 00:01:00,300
‫walking through the entire application

18
00:01:00,300 --> 00:01:03,750
‫to check if there are any performance bottlenecks.

19
00:01:03,750 --> 00:01:06,390
‫So to see if there is any component

20
00:01:06,390 --> 00:01:09,390
‫that might perform really badly.

21
00:01:09,390 --> 00:01:13,530
‫So let's start profiling, and then let's just follow

22
00:01:13,530 --> 00:01:15,363
‫the flow of the application.

23
00:01:16,380 --> 00:01:21,380
‫So we can go to all of these different components or pages,

24
00:01:21,540 --> 00:01:23,373
‫and then of course we can log in.

25
00:01:24,270 --> 00:01:29,270
‫We can click somewhere here, go back, click on a city,

26
00:01:31,050 --> 00:01:35,163
‫maybe on the countries, maybe here, and then log out.

27
00:01:36,090 --> 00:01:40,710
‫So just experimenting everything, and then let's finish.

28
00:01:40,710 --> 00:01:45,330
‫And you see that we have a lot of renders.

29
00:01:45,330 --> 00:01:49,140
‫So we created 21 renders in total.

30
00:01:49,140 --> 00:01:53,433
‫And so let's now see if any of them was really slow.

31
00:01:54,300 --> 00:01:56,970
‫So in order to identify some really

32
00:01:56,970 --> 00:02:00,450
‫bad performing components, it's best to come here

33
00:02:00,450 --> 00:02:02,340
‫to the ranked tab.

34
00:02:02,340 --> 00:02:06,060
‫And so we see that the component that took the most time

35
00:02:06,060 --> 00:02:09,210
‫in the first render was this route.

36
00:02:09,210 --> 00:02:12,330
‫So that took less than one milliseconds,

37
00:02:12,330 --> 00:02:14,640
‫which is really nothing.

38
00:02:14,640 --> 00:02:16,860
‫So remember that in the previous app

39
00:02:16,860 --> 00:02:19,500
‫when we were experimenting with the archive,

40
00:02:19,500 --> 00:02:24,500
‫we sometimes had 200 milliseconds or 100 milliseconds.

41
00:02:24,810 --> 00:02:27,270
‫And of course these values are different

42
00:02:27,270 --> 00:02:30,060
‫on your computer than they are on mine.

43
00:02:30,060 --> 00:02:33,720
‫Different, but still, this is like an order of magnitude

44
00:02:33,720 --> 00:02:36,390
‫faster than what we had before.

45
00:02:36,390 --> 00:02:40,260
‫So nothing to worry here, and so let's keep going.

46
00:02:40,260 --> 00:02:42,870
‫So we just click here, and then we see

47
00:02:42,870 --> 00:02:46,770
‫all the components that rendered and how fast.

48
00:02:46,770 --> 00:02:48,720
‫So let's just quickly go through them

49
00:02:48,720 --> 00:02:52,413
‫just to identify if anything was really slow.

50
00:02:54,840 --> 00:02:59,040
‫So the most that we saw up until this point is this one,

51
00:02:59,040 --> 00:03:02,073
‫two milliseconds, which again, is really nothing.

52
00:03:03,420 --> 00:03:06,480
‫So it seems like in this application

53
00:03:06,480 --> 00:03:10,053
‫we have absolutely no problem with performance,

54
00:03:12,180 --> 00:03:14,493
‫which of course is very nice to see.

55
00:03:15,420 --> 00:03:19,170
‫So let's just clean this, and maybe let's just analyze

56
00:03:19,170 --> 00:03:21,723
‫one state's transition here.

57
00:03:22,740 --> 00:03:26,430
‫So maybe here at this login part just to see a bit

58
00:03:26,430 --> 00:03:27,843
‫what actually happens.

59
00:03:29,730 --> 00:03:34,053
‫So just that navigation was actually four state updates.

60
00:03:35,340 --> 00:03:37,650
‫So here in the flame graph we can see

61
00:03:37,650 --> 00:03:41,700
‫that first the off provider was re-rendered,

62
00:03:41,700 --> 00:03:44,340
‫which then made the login form

63
00:03:44,340 --> 00:03:46,323
‫and all its children re-rendered.

64
00:03:47,850 --> 00:03:52,850
‫Then, next up we saw that our router basically re-rendered.

65
00:03:53,370 --> 00:03:56,283
‫So in order to move us to the next page.

66
00:03:57,570 --> 00:04:00,210
‫So that's all of this stuff right here,

67
00:04:00,210 --> 00:04:03,780
‫and of course you start seeing that once we add

68
00:04:03,780 --> 00:04:06,120
‫all of these components to our tree,

69
00:04:06,120 --> 00:04:08,553
‫it becomes all a bit more confusing.

70
00:04:10,320 --> 00:04:13,413
‫All right, now what do we have here?

71
00:04:14,250 --> 00:04:18,210
‫This is probably coming from the React Leaflet library.

72
00:04:18,210 --> 00:04:19,920
‫So it's inside the map.

73
00:04:19,920 --> 00:04:23,100
‫And then here we have some components

74
00:04:23,100 --> 00:04:25,440
‫that are updating inside there.

75
00:04:25,440 --> 00:04:29,370
‫And so yeah, these are related to positioning the map,

76
00:04:29,370 --> 00:04:32,760
‫probably, and then finally we have another render,

77
00:04:32,760 --> 00:04:35,700
‫which was caused by our router.

78
00:04:35,700 --> 00:04:38,520
‫So that's what we can see here on the side.

79
00:04:38,520 --> 00:04:41,130
‫So as we go through here, we can always see

80
00:04:41,130 --> 00:04:43,023
‫what caused this update.

81
00:04:44,040 --> 00:04:45,750
‫So here it was again the router,

82
00:04:45,750 --> 00:04:48,649
‫and here it was the AuthProvider.

83
00:04:48,649 --> 00:04:50,610
‫So because we logged the user in,

84
00:04:50,610 --> 00:04:52,710
‫then the AuthProvider re-rendered,

85
00:04:52,710 --> 00:04:54,723
‫which then triggered all of this.

86
00:04:56,040 --> 00:04:59,790
‫Okay, and of course you can now analyze this a lot more

87
00:04:59,790 --> 00:05:03,330
‫if you feel like, and if you want to have some fun

88
00:05:03,330 --> 00:05:05,010
‫with this tool.

89
00:05:05,010 --> 00:05:08,070
‫But for now, let's go back here to our code

90
00:05:08,070 --> 00:05:09,780
‫to see what we can do.

91
00:05:09,780 --> 00:05:13,140
‫And actually not a lot, as I was saying,

92
00:05:13,140 --> 00:05:16,293
‫because everything is working really fluidly.

93
00:05:17,850 --> 00:05:21,000
‫So earlier we were optimizing our context,

94
00:05:21,000 --> 00:05:24,360
‫but even here there's not much to do.

95
00:05:24,360 --> 00:05:28,590
‫Let's just delete this useState that we no longer need.

96
00:05:28,590 --> 00:05:32,280
‫But yeah, so again, there's not a lot

97
00:05:32,280 --> 00:05:36,420
‫to optimize here in this context.

98
00:05:36,420 --> 00:05:39,570
‫So that's because we don't have any performance issues,

99
00:05:39,570 --> 00:05:44,340
‫and also because the way that we set up our context value.

100
00:05:44,340 --> 00:05:48,450
‫So remember how earlier we decided that we want to pass in

101
00:05:48,450 --> 00:05:51,780
‫all of these functions into the context value,

102
00:05:51,780 --> 00:05:54,300
‫and so therefore it wouldn't be practical

103
00:05:54,300 --> 00:05:59,160
‫to create one separate context for each of them, right?

104
00:05:59,160 --> 00:06:02,460
‫So that's one of the strategies that I mentioned earlier,

105
00:06:02,460 --> 00:06:07,460
‫but that's not really practical and also not necessary here.

106
00:06:07,530 --> 00:06:11,100
‫Also, there's not really a need to memorize

107
00:06:11,100 --> 00:06:14,910
‫this value right here, because we don't have any component

108
00:06:14,910 --> 00:06:18,150
‫above this provider in the component tree

109
00:06:18,150 --> 00:06:20,610
‫that might re-render this one.

110
00:06:20,610 --> 00:06:23,970
‫And so there's no point in doing that,

111
00:06:23,970 --> 00:06:27,690
‫and so I think that there's actually nothing to do here,

112
00:06:27,690 --> 00:06:28,653
‫which is good.

113
00:06:30,450 --> 00:06:34,830
‫Now, let's just remember that there was some issue earlier.

114
00:06:34,830 --> 00:06:38,010
‫And so we are now actually ready to fix that.

115
00:06:38,010 --> 00:06:41,880
‫So if we come back here to our city,

116
00:06:41,880 --> 00:06:44,190
‫remember that in the use effect,

117
00:06:44,190 --> 00:06:47,490
‫we left out the getCity function.

118
00:06:47,490 --> 00:06:52,020
‫So here we see that issue where eslint is telling us

119
00:06:52,020 --> 00:06:56,790
‫to add the getCity, but remember that this created

120
00:06:56,790 --> 00:07:01,440
‫an infinite loop of HTTP requests to our API.

121
00:07:01,440 --> 00:07:03,153
‫But let's do that again now.

122
00:07:04,380 --> 00:07:09,380
‫So getCity, then let's just reload here,

123
00:07:12,780 --> 00:07:17,780
‫and maybe let's come actually to the network tab,

124
00:07:18,510 --> 00:07:21,420
‫clean all of this, and then watch what happens

125
00:07:21,420 --> 00:07:23,613
‫when I click on one of these cities.

126
00:07:24,450 --> 00:07:28,500
‫And indeed, immediately we get like a thousand requests,

127
00:07:28,500 --> 00:07:31,170
‫and it keeps going even though the number here

128
00:07:31,170 --> 00:07:32,970
‫is not going up.

129
00:07:32,970 --> 00:07:36,750
‫But we can also see down here that every second or so

130
00:07:36,750 --> 00:07:38,763
‫there is a new request coming in.

131
00:07:42,420 --> 00:07:45,933
‫And even here it's of course also very visible.

132
00:07:47,340 --> 00:07:50,913
‫Now, we can even see the same in the profiler.

133
00:07:51,930 --> 00:07:56,930
‫So if we go back and then start profiling clicking here,

134
00:07:58,350 --> 00:08:00,813
‫and then I will just leave it for a few seconds.

135
00:08:02,280 --> 00:08:03,990
‫That should be enough.

136
00:08:03,990 --> 00:08:07,110
‫And you see that we have 60 state updates

137
00:08:07,110 --> 00:08:10,470
‫only in this three seconds that I waited.

138
00:08:10,470 --> 00:08:13,770
‫And so clearly there is something wrong here,

139
00:08:13,770 --> 00:08:17,070
‫and this is the only thing that we need to fix now

140
00:08:17,070 --> 00:08:19,890
‫using the tools that we learned before.

141
00:08:19,890 --> 00:08:22,830
‫But first of all, of course, we need to understand

142
00:08:22,830 --> 00:08:24,753
‫what is actually happening.

143
00:08:25,800 --> 00:08:28,710
‫So now that we have this getCity function

144
00:08:28,710 --> 00:08:32,280
‫in our dependency array, the effect will rerun

145
00:08:32,280 --> 00:08:36,060
‫each time that it get city function gets updated,

146
00:08:36,060 --> 00:08:39,510
‫or in other words, that it gets recreated.

147
00:08:39,510 --> 00:08:42,930
‫Now, when does this function get recreated?

148
00:08:42,930 --> 00:08:47,930
‫Well, since it lives in the context, so let's open that.

149
00:08:49,650 --> 00:08:53,850
‫So this file, getCity, lives here,

150
00:08:53,850 --> 00:08:57,810
‫so it is created in this city's provider.

151
00:08:57,810 --> 00:09:02,790
‫But the problem is that this getCity function

152
00:09:02,790 --> 00:09:06,780
‫will update the state each time that it is executed,

153
00:09:06,780 --> 00:09:09,753
‫which will then end up in an infinite loop.

154
00:09:11,850 --> 00:09:16,320
‫So here we call the getCity function, right?

155
00:09:16,320 --> 00:09:19,110
‫And so that function will then update the state

156
00:09:19,110 --> 00:09:20,790
‫in this component.

157
00:09:20,790 --> 00:09:23,340
‫Then this component will re-render,

158
00:09:23,340 --> 00:09:26,160
‫which will then recreate this function.

159
00:09:26,160 --> 00:09:28,440
‫And as the function gets recreated,

160
00:09:28,440 --> 00:09:30,720
‫since it is here in the dependency array,

161
00:09:30,720 --> 00:09:33,150
‫then getCity will get called again,

162
00:09:33,150 --> 00:09:36,360
‫which then again will update a state, which will re-render,

163
00:09:36,360 --> 00:09:39,480
‫which will cause the effect to run over,

164
00:09:39,480 --> 00:09:41,850
‫and over, and over again.

165
00:09:41,850 --> 00:09:44,973
‫So that's the infinite loop that we have right here,

166
00:09:45,810 --> 00:09:48,270
‫and probably we should come back here

167
00:09:48,270 --> 00:09:52,620
‫and now take our application out of this misery.

168
00:09:52,620 --> 00:09:56,460
‫So it's been fetching for a few minutes now,

169
00:09:56,460 --> 00:09:58,590
‫so that's a bit too much.

170
00:09:58,590 --> 00:10:02,340
‫But anyway, how do you think we can fix this?

171
00:10:02,340 --> 00:10:04,590
‫So the solution is not to remove this

172
00:10:04,590 --> 00:10:06,060
‫from the dependency array,

173
00:10:06,060 --> 00:10:09,210
‫because that is not allowed in React.

174
00:10:09,210 --> 00:10:13,530
‫Instead, what we need to do is to make this function stable.

175
00:10:13,530 --> 00:10:18,150
‫So we need it to not be recreated on each re-render.

176
00:10:18,150 --> 00:10:21,570
‫And the way we do that, as you hopefully know,

177
00:10:21,570 --> 00:10:24,363
‫is by using the useCallback hook.

178
00:10:26,190 --> 00:10:28,950
‫So let's create a new variable,

179
00:10:28,950 --> 00:10:31,983
‫which will be the new getCity function,

180
00:10:32,970 --> 00:10:36,543
‫and this will then be the result of calling useCallback.

181
00:10:40,350 --> 00:10:45,300
‫All right, then our dependency array,

182
00:10:45,300 --> 00:10:48,913
‫which will need probably this currentCity.

183
00:10:50,370 --> 00:10:51,810
‫And there it is.

184
00:10:51,810 --> 00:10:55,740
‫So currentCity.id, and once again,

185
00:10:55,740 --> 00:10:59,070
‫just having this kind of warning here

186
00:10:59,070 --> 00:11:02,730
‫is reason enough to really always install eslint

187
00:11:02,730 --> 00:11:03,930
‫in your projects.

188
00:11:03,930 --> 00:11:06,573
‫So without it, you'll create so many bugs,

189
00:11:07,800 --> 00:11:09,453
‫it's not gonna be funny, really.

190
00:11:10,440 --> 00:11:15,090
‫But anyway, this now shows you a real world use case

191
00:11:15,090 --> 00:11:19,380
‫of this hook, so of this useCallback hook right here.

192
00:11:19,380 --> 00:11:22,050
‫So this is one of these real world situations

193
00:11:22,050 --> 00:11:25,710
‫in which you will really need to reach for this tool.

194
00:11:25,710 --> 00:11:28,140
‫So that's why it's really important

195
00:11:28,140 --> 00:11:32,310
‫that you paid good attention throughout this section.

196
00:11:32,310 --> 00:11:36,330
‫And actually remember that when I first introduced

197
00:11:36,330 --> 00:11:40,470
‫these hooks, this was exactly one of the three use cases

198
00:11:40,470 --> 00:11:41,760
‫that I talked about.

199
00:11:41,760 --> 00:11:45,450
‫So memorizing values that are used in the dependency array

200
00:11:45,450 --> 00:11:48,903
‫of another hook in order to prevent infinite loops.

201
00:11:51,060 --> 00:11:53,883
‫So let's give it a reload here,

202
00:11:54,900 --> 00:11:57,933
‫and then let's just try it again.

203
00:11:59,160 --> 00:12:02,490
‫And if we come here to our network tab,

204
00:12:02,490 --> 00:12:05,940
‫then we see that there is no problem anymore.

205
00:12:05,940 --> 00:12:07,770
‫And also here we are not seeing

206
00:12:07,770 --> 00:12:10,203
‫these infinite requests coming in.

207
00:12:11,280 --> 00:12:13,560
‫All right, and this is actually

208
00:12:13,560 --> 00:12:17,040
‫all that I wanted to show you in this lecture.

209
00:12:17,040 --> 00:12:19,530
‫And I can understand that it probably

210
00:12:19,530 --> 00:12:21,510
‫seems pretty intimidating,

211
00:12:21,510 --> 00:12:24,210
‫for example, to find out by yourself

212
00:12:24,210 --> 00:12:26,910
‫that this would've been the solution here.

213
00:12:26,910 --> 00:12:30,420
‫But trust me, that with practice and with study,

214
00:12:30,420 --> 00:12:32,880
‫you will be able to really understand

215
00:12:32,880 --> 00:12:34,803
‫and to master all these tools.

