WEBVTT

1
00:00:00.000 --> 00:00:02.799
<v Speaker 1>All right, let's kick things off today. We're going deep

2
00:00:02.839 --> 00:00:07.080
<v Speaker 1>on ACYNK JavaScript and how to write code that's not

3
00:00:07.160 --> 00:00:10.480
<v Speaker 1>just functional but really sings performance wise.

4
00:00:10.759 --> 00:00:12.679
<v Speaker 2>Yeah, we're talking speed exactly.

5
00:00:13.320 --> 00:00:16.039
<v Speaker 1>And to guide us on this journey, we have Kyle

6
00:00:16.079 --> 00:00:19.600
<v Speaker 1>Simpson's book You Don't Know JS, A sink and Performance.

7
00:00:19.800 --> 00:00:22.519
<v Speaker 2>It's a fantastic resource, really digs deep.

8
00:00:22.640 --> 00:00:25.280
<v Speaker 1>I've got to say this book was a game changer

9
00:00:25.320 --> 00:00:25.559
<v Speaker 1>for me.

10
00:00:25.760 --> 00:00:26.399
<v Speaker 2>Absolutely.

11
00:00:26.640 --> 00:00:29.600
<v Speaker 1>When I first started with ACYNK JavaScript, it felt like

12
00:00:29.920 --> 00:00:31.760
<v Speaker 1>I don't know, my brain was doing backflips.

13
00:00:31.839 --> 00:00:33.920
<v Speaker 2>It's definitely a mind bender, especially that.

14
00:00:33.920 --> 00:00:37.920
<v Speaker 1>Whole concept of later. You know how JavaScript handles things

15
00:00:37.960 --> 00:00:41.119
<v Speaker 1>that can't happen right away right right. It's not exactly intuitive.

16
00:00:41.200 --> 00:00:44.079
<v Speaker 2>It's like we assume later means well right.

17
00:00:44.000 --> 00:00:46.039
<v Speaker 1>After now, Yeah, like step one, step two.

18
00:00:45.960 --> 00:00:48.479
<v Speaker 2>But in javascripts later it's a whole different beast.

19
00:00:48.679 --> 00:00:51.039
<v Speaker 1>So let's say you're making an ajax call to grab

20
00:00:51.079 --> 00:00:53.640
<v Speaker 1>some data from a server. Okay, you write the code,

21
00:00:53.759 --> 00:00:55.799
<v Speaker 1>you make the call, and then you try to log

22
00:00:55.840 --> 00:00:58.920
<v Speaker 1>the data. You know, right after it seems logical, yeah,

23
00:00:58.960 --> 00:01:00.320
<v Speaker 1>but then nothing.

24
00:01:00.159 --> 00:01:03.960
<v Speaker 2>It's like where the data go proof vanish. The trick

25
00:01:04.079 --> 00:01:07.400
<v Speaker 2>is we're thinking in a straight line but when you're

26
00:01:07.439 --> 00:01:11.879
<v Speaker 2>dealing with things like timers, clicks, those AgeX responses, we're

27
00:01:11.879 --> 00:01:13.439
<v Speaker 2>in the land of a synchronicity.

28
00:01:13.680 --> 00:01:16.439
<v Speaker 1>Okay, so things are getting shuffled around exactly.

29
00:01:16.560 --> 00:01:18.760
<v Speaker 2>Things don't always happen in a predictable order.

30
00:01:18.920 --> 00:01:21.879
<v Speaker 1>So how does JavaScript decide what happens now versus what

31
00:01:21.959 --> 00:01:24.879
<v Speaker 1>gets pushed to this mysterious later.

32
00:01:25.159 --> 00:01:27.719
<v Speaker 2>It all comes down to this thing called the event loop.

33
00:01:27.959 --> 00:01:29.280
<v Speaker 1>Okay, the event loop.

34
00:01:29.319 --> 00:01:31.760
<v Speaker 2>Think of it like a queue, a never ending queue of.

35
00:01:31.719 --> 00:01:34.719
<v Speaker 1>Tasks, all right. So each task gets.

36
00:01:34.480 --> 00:01:37.799
<v Speaker 2>Its turn exactly, Each task gets its moment to run,

37
00:01:37.879 --> 00:01:40.280
<v Speaker 2>and then boom, event loop moves on to the next one.

38
00:01:40.400 --> 00:01:43.280
<v Speaker 1>It's like a very organized but super fast game of

39
00:01:43.400 --> 00:01:44.200
<v Speaker 1>musical chairs.

40
00:01:44.560 --> 00:01:45.079
<v Speaker 2>You got it.

41
00:01:45.280 --> 00:01:46.719
<v Speaker 1>But what about set time out?

42
00:01:47.079 --> 00:01:47.519
<v Speaker 2>Ah?

43
00:01:47.640 --> 00:01:50.200
<v Speaker 1>Set time out is just like chuck the function into

44
00:01:50.280 --> 00:01:51.040
<v Speaker 1>queue immediately.

45
00:01:51.239 --> 00:01:54.400
<v Speaker 2>Not quite. It's more like it sets a timer okay,

46
00:01:54.439 --> 00:01:56.319
<v Speaker 2>and when the timer goes off, it's like the function

47
00:01:56.480 --> 00:01:58.640
<v Speaker 2>taps the event loop on the shoulder and says, hey,

48
00:01:58.680 --> 00:01:59.319
<v Speaker 2>I'm ready now.

49
00:01:59.400 --> 00:02:02.200
<v Speaker 1>Ah. It's like a reservation system for our code.

50
00:02:02.359 --> 00:02:03.920
<v Speaker 2>I like that, a reservation system.

51
00:02:04.120 --> 00:02:06.400
<v Speaker 1>But this brings up something that's always tripped me up.

52
00:02:06.840 --> 00:02:11.879
<v Speaker 1>What's concurrency? Ah? Concurrency what happens when multiple things are

53
00:02:11.919 --> 00:02:13.199
<v Speaker 1>trying to happen at the same time.

54
00:02:13.800 --> 00:02:17.159
<v Speaker 2>It's a great question and important to remember. Even though

55
00:02:17.240 --> 00:02:21.439
<v Speaker 2>JavaScript doesn't have traditional threads, we still have to deal

56
00:02:21.479 --> 00:02:25.400
<v Speaker 2>with concurrency because at its heart it's single threaded.

57
00:02:25.680 --> 00:02:28.599
<v Speaker 1>So it's like having one chef trying to cook multiple

58
00:02:28.599 --> 00:02:29.280
<v Speaker 1>dishes at once.

59
00:02:29.560 --> 00:02:32.240
<v Speaker 2>Exactly. They can only work on one thing at a time,

60
00:02:32.400 --> 00:02:34.479
<v Speaker 2>but they've got to keep switching back and forth.

61
00:02:34.560 --> 00:02:36.719
<v Speaker 1>So how do we make sure we're not creating kitchen

62
00:02:36.879 --> 00:02:38.639
<v Speaker 1>chaos in our code? Right?

63
00:02:38.719 --> 00:02:40.000
<v Speaker 2>We don't want everything burning?

64
00:02:40.199 --> 00:02:44.280
<v Speaker 1>What happens when multiple functions try to access and you know,

65
00:02:44.560 --> 00:02:46.280
<v Speaker 1>change the same data at the same time.

66
00:02:46.479 --> 00:02:49.120
<v Speaker 2>It can get messy. But one way to manage this

67
00:02:49.240 --> 00:02:51.360
<v Speaker 2>is using something called mutual exclusion.

68
00:02:51.560 --> 00:02:53.039
<v Speaker 1>Mutual exclusion okay, like.

69
00:02:53.000 --> 00:02:55.159
<v Speaker 2>Putting a lock on a shared resource.

70
00:02:54.759 --> 00:02:57.000
<v Speaker 1>So only one function can access it at a time.

71
00:02:57.400 --> 00:02:59.319
<v Speaker 2>You got it. You can think of it like a

72
00:02:59.400 --> 00:03:03.080
<v Speaker 2>simple if statement that checks if a variable is being used.

73
00:03:03.479 --> 00:03:05.919
<v Speaker 1>So it's like those occupied signs on a restroom stall.

74
00:03:06.080 --> 00:03:07.080
<v Speaker 2>Perfect analogy.

75
00:03:07.080 --> 00:03:09.680
<v Speaker 1>It's got a wait, it's turned exactly now, what about

76
00:03:09.680 --> 00:03:12.680
<v Speaker 1>breaking down those tasks into smaller chunks?

77
00:03:12.800 --> 00:03:15.039
<v Speaker 2>Ah, you're talking about cooperative concurrency.

78
00:03:15.240 --> 00:03:15.759
<v Speaker 1>That's it.

79
00:03:15.759 --> 00:03:17.400
<v Speaker 2>It's all about sharing the stage.

80
00:03:17.479 --> 00:03:20.879
<v Speaker 1>So instead of one function hogging the event loop for ages,

81
00:03:20.919 --> 00:03:21.560
<v Speaker 1>we break.

82
00:03:21.319 --> 00:03:24.159
<v Speaker 2>It down right into smaller steps, give other functions a

83
00:03:24.240 --> 00:03:25.240
<v Speaker 2>chance to run, so.

84
00:03:25.159 --> 00:03:28.520
<v Speaker 1>We avoid that event loop traffic jam exactly. Okay. I

85
00:03:29.080 --> 00:03:31.719
<v Speaker 1>gotta be honest, though, the fact that JavaScript can actually

86
00:03:31.759 --> 00:03:34.800
<v Speaker 1>re order statements in my code, that kind of freaks

87
00:03:34.840 --> 00:03:35.159
<v Speaker 1>me out.

88
00:03:35.280 --> 00:03:37.319
<v Speaker 2>I get it. It feels like our code is being

89
00:03:37.400 --> 00:03:41.159
<v Speaker 2>rearranged behind our backs, right, But remember the JavaScript engine,

90
00:03:41.639 --> 00:03:44.800
<v Speaker 2>it's smart, okay. It's always looking for ways to optimize

91
00:03:44.840 --> 00:03:47.479
<v Speaker 2>our code, and sometimes that means rearranging things as long

92
00:03:47.520 --> 00:03:49.000
<v Speaker 2>as the final result is the same.

93
00:03:49.199 --> 00:03:51.159
<v Speaker 1>So it's like having a super efficient editor.

94
00:03:51.400 --> 00:03:51.960
<v Speaker 2>Exactly.

95
00:03:52.120 --> 00:03:54.319
<v Speaker 1>They clean up our writing, but the meaning stays the

96
00:03:54.360 --> 00:03:56.680
<v Speaker 1>same precisely. That makes me feel a bit better.

97
00:03:56.759 --> 00:03:58.639
<v Speaker 2>Good, good, But it still.

98
00:03:58.400 --> 00:04:01.280
<v Speaker 1>Makes it hard to picture, you know, what happens when,

99
00:04:01.680 --> 00:04:04.000
<v Speaker 1>especially with all these asynchronous events flying around.

100
00:04:04.240 --> 00:04:08.120
<v Speaker 2>It's true we're wired for linear thinking, but asynchronous code

101
00:04:08.159 --> 00:04:11.479
<v Speaker 2>it's much more fluid. Ye think about trying to run

102
00:04:11.639 --> 00:04:14.280
<v Speaker 2>errands and take phone calls at the same time. Oh yeah,

103
00:04:14.400 --> 00:04:16.879
<v Speaker 2>You start one task, get interrupted by a call, go

104
00:04:16.959 --> 00:04:18.480
<v Speaker 2>back to the task, interrupted again.

105
00:04:18.639 --> 00:04:22.759
<v Speaker 1>It's impossible to plan everything perfectly in a straight line, exactly.

106
00:04:23.040 --> 00:04:25.079
<v Speaker 2>You can't predict when those calls are going to come in.

107
00:04:25.319 --> 00:04:29.279
<v Speaker 1>And I feel like that chaotic feeling gets amplified when

108
00:04:29.279 --> 00:04:31.000
<v Speaker 1>we start using nested callbacks.

109
00:04:31.199 --> 00:04:33.519
<v Speaker 2>Oh, nested callbacks they can get out of hand.

110
00:04:33.879 --> 00:04:36.519
<v Speaker 1>It's like following a recipe where every step sends you

111
00:04:36.560 --> 00:04:38.600
<v Speaker 1>on a wild goose chase for another ingredient.

112
00:04:38.800 --> 00:04:40.639
<v Speaker 2>Right, You're jumping all over the place.

113
00:04:40.399 --> 00:04:41.800
<v Speaker 1>And then you end up with a kitchen that looks

114
00:04:41.839 --> 00:04:42.839
<v Speaker 1>like a tornado hit.

115
00:04:42.720 --> 00:04:46.160
<v Speaker 2>It, exactly. And nested callbacks they can turn into a

116
00:04:46.199 --> 00:04:47.000
<v Speaker 2>tangled mess.

117
00:04:47.319 --> 00:04:50.360
<v Speaker 1>They make our code harder to understand, harder to debug,

118
00:04:50.800 --> 00:04:54.480
<v Speaker 1>harder to maintain. Absolutely, which brings us to the well,

119
00:04:54.560 --> 00:04:58.560
<v Speaker 1>the darker side of callbacks. Ooh, what's that the trust issues?

120
00:04:58.639 --> 00:05:00.839
<v Speaker 2>Trust issues with a our own code.

121
00:05:01.120 --> 00:05:03.959
<v Speaker 1>Yeah, shouldn't we be able to trust ourselves ideally?

122
00:05:04.120 --> 00:05:08.439
<v Speaker 2>Yes, but remember in this acinc world, things get unpredictable.

123
00:05:09.120 --> 00:05:11.959
<v Speaker 2>Even our own code can behave in ways we don't expect,

124
00:05:12.319 --> 00:05:14.839
<v Speaker 2>especially when we're dealing with external libraries.

125
00:05:15.079 --> 00:05:16.279
<v Speaker 1>Okay, you're losing me a little.

126
00:05:16.399 --> 00:05:19.600
<v Speaker 2>Okay, imagine this. Yeah, you're adding a third party analytics

127
00:05:19.600 --> 00:05:22.639
<v Speaker 2>tool to your website. You know, for tracking purchases. Okay, yeah,

128
00:05:22.680 --> 00:05:25.879
<v Speaker 2>you hand over your purchase data to their library. Everything

129
00:05:25.920 --> 00:05:28.959
<v Speaker 2>seems to be working fine. You pat yourself on the back. Job,

130
00:05:29.000 --> 00:05:33.040
<v Speaker 2>well done, right, good job. Months later, your boss calls panicked.

131
00:05:33.560 --> 00:05:37.199
<v Speaker 2>Oh no, a customer was charged five times for the

132
00:05:37.240 --> 00:05:37.959
<v Speaker 2>same item.

133
00:05:38.199 --> 00:05:39.800
<v Speaker 1>Oh that's a nightmare.

134
00:05:39.959 --> 00:05:42.959
<v Speaker 2>It is. And after some frantic debugging, you find out

135
00:05:43.000 --> 00:05:47.160
<v Speaker 2>that the analytics library was silently retrying the purchase callback

136
00:05:47.319 --> 00:05:49.639
<v Speaker 2>multiple times, leading to those duplicate charges.

137
00:05:49.879 --> 00:05:51.720
<v Speaker 1>It's like handing over the keys to your car and

138
00:05:51.759 --> 00:05:53.360
<v Speaker 1>hoping they won't go on a joy ride.

139
00:05:53.560 --> 00:05:56.720
<v Speaker 2>That's exactly the problem with callbacks, this inversion of control.

140
00:05:56.839 --> 00:05:59.639
<v Speaker 1>We're handing over control and just hoping for the best.

141
00:05:59.800 --> 00:06:01.600
<v Speaker 2>Right, But there's a better way.

142
00:06:01.720 --> 00:06:05.199
<v Speaker 1>Tell me, there's a better way. Promises promises, those sound promising,

143
00:06:05.279 --> 00:06:06.040
<v Speaker 1>They tell me more.

144
00:06:06.480 --> 00:06:10.319
<v Speaker 2>A promise is essentially a contract for a future.

145
00:06:10.079 --> 00:06:12.879
<v Speaker 1>Value, so like a guarantee in a way.

146
00:06:13.040 --> 00:06:14.920
<v Speaker 2>Yeah, it's like saying, I promise to get back to

147
00:06:14.959 --> 00:06:16.800
<v Speaker 2>you with the result of this operation.

148
00:06:16.600 --> 00:06:18.240
<v Speaker 1>Whether it's a success or a failure.

149
00:06:18.439 --> 00:06:19.000
<v Speaker 2>Exactly.

150
00:06:19.199 --> 00:06:23.160
<v Speaker 1>So, instead of relying on this potentially flaky callback, we

151
00:06:23.240 --> 00:06:24.680
<v Speaker 1>have a more structured approach.

152
00:06:25.240 --> 00:06:28.240
<v Speaker 2>It's more reliable. I like it, and with promises, we

153
00:06:28.319 --> 00:06:30.399
<v Speaker 2>keep control over the flow of execution.

154
00:06:31.000 --> 00:06:33.480
<v Speaker 1>Okay, so we get to decide what happens next exactly.

155
00:06:33.839 --> 00:06:36.920
<v Speaker 2>We define what should happen when the promise is fulfilled

156
00:06:37.360 --> 00:06:41.120
<v Speaker 2>meaning the operation was successful, or rejected meaning there was

157
00:06:41.160 --> 00:06:41.720
<v Speaker 2>an error.

158
00:06:42.000 --> 00:06:44.959
<v Speaker 1>Okay, promises sound like a much safer bet they are.

159
00:06:45.279 --> 00:06:47.399
<v Speaker 1>Could you walk me through an example. Maybe you know

160
00:06:47.439 --> 00:06:49.000
<v Speaker 1>with our trustee ajax call.

161
00:06:49.279 --> 00:06:52.879
<v Speaker 2>Absolutely, So instead of passing a callback function to that

162
00:06:52.920 --> 00:06:56.399
<v Speaker 2>ajax call, we create a promise that represents the result

163
00:06:56.439 --> 00:06:59.839
<v Speaker 2>of the request Okay, and then, using the then method,

164
00:07:00.240 --> 00:07:03.920
<v Speaker 2>we specify what should happen when the promise resolves successfully.

165
00:07:04.040 --> 00:07:06.199
<v Speaker 1>So it's like, if this happens, then do this you

166
00:07:06.279 --> 00:07:06.680
<v Speaker 1>got it?

167
00:07:07.199 --> 00:07:09.439
<v Speaker 2>And if something goes wrong, we can use the catch

168
00:07:09.480 --> 00:07:12.879
<v Speaker 2>method to handle the error gracefully prevents our app from crashing.

169
00:07:13.000 --> 00:07:16.560
<v Speaker 1>Okay. So promises make our asynchronous code more robust and

170
00:07:16.639 --> 00:07:20.959
<v Speaker 1>predictable exactly. But what about when we have multiple asynchronous

171
00:07:21.000 --> 00:07:22.879
<v Speaker 1>operations we need to do in sequence.

172
00:07:23.040 --> 00:07:26.120
<v Speaker 2>Ah, That's where the magic of promise chaining comes in.

173
00:07:26.319 --> 00:07:28.639
<v Speaker 1>Okay, promise chaining, you can use the.

174
00:07:28.519 --> 00:07:32.759
<v Speaker 2>Then method to chain together a series of asynchronous steps.

175
00:07:32.480 --> 00:07:35.240
<v Speaker 1>Each one depending on the one before it exactly.

176
00:07:35.279 --> 00:07:38.040
<v Speaker 2>It's like a domino effect. Each step triggers the next.

177
00:07:38.160 --> 00:07:40.720
<v Speaker 1>Okay, so instead of juggling all these promises at once,

178
00:07:41.319 --> 00:07:44.759
<v Speaker 1>we create this smooth, organized flow precisely.

179
00:07:45.160 --> 00:07:47.839
<v Speaker 2>It's all about creating a clear sequence of events.

180
00:07:48.079 --> 00:07:50.519
<v Speaker 1>I love it. But what about situations where we have

181
00:07:50.720 --> 00:07:54.160
<v Speaker 1>multiple promises happening concurrently, Like let's say we need to

182
00:07:54.160 --> 00:07:57.040
<v Speaker 1>fetch data from multiple URLs at the same time.

183
00:07:57.240 --> 00:08:00.519
<v Speaker 2>Ah, for that, we have promise at all at all.

184
00:08:00.680 --> 00:08:02.439
<v Speaker 2>It's like waiting for all your friends to get ready

185
00:08:02.480 --> 00:08:03.560
<v Speaker 2>before you head out for the night.

186
00:08:03.680 --> 00:08:05.839
<v Speaker 1>You pass it in an array of promises.

187
00:08:05.439 --> 00:08:07.279
<v Speaker 2>Yep, and it gives you back a new promise that

188
00:08:07.399 --> 00:08:09.560
<v Speaker 2>resolves when all of those promises have resolved.

189
00:08:09.720 --> 00:08:13.079
<v Speaker 1>So it's like okay, everyone's here, let's go exactly.

190
00:08:13.519 --> 00:08:17.839
<v Speaker 2>And the best part is Promise all gathers all the

191
00:08:17.879 --> 00:08:21.399
<v Speaker 2>results from those promises into a nice array, so you

192
00:08:21.399 --> 00:08:23.360
<v Speaker 2>can work with the combined data easily.

193
00:08:23.959 --> 00:08:28.759
<v Speaker 1>Okay, So promises can handle these complex scenarios, both sequential

194
00:08:28.920 --> 00:08:30.399
<v Speaker 1>and concurrent.

195
00:08:30.399 --> 00:08:31.399
<v Speaker 2>They're very versatile.

196
00:08:31.480 --> 00:08:34.679
<v Speaker 1>I'm impressed I did. But earlier we were talking about

197
00:08:34.720 --> 00:08:38.519
<v Speaker 1>you know, those nested callback nightmares with event handlers. Oh yeah,

198
00:08:38.759 --> 00:08:40.360
<v Speaker 1>can promises help us out there too.

199
00:08:40.639 --> 00:08:43.360
<v Speaker 2>They can, but we got to be careful. Okay, if

200
00:08:43.399 --> 00:08:46.080
<v Speaker 2>we're not careful, we might just be trading one type

201
00:08:46.080 --> 00:08:47.279
<v Speaker 2>of complexity for another.

202
00:08:47.480 --> 00:08:47.840
<v Speaker 1>Okay.

203
00:08:47.960 --> 00:08:51.679
<v Speaker 2>Creating a new promise chain inside each event handler can get.

204
00:08:51.480 --> 00:08:53.120
<v Speaker 1>Messy, right, redundant code.

205
00:08:53.320 --> 00:08:54.519
<v Speaker 2>It makes things hard to manage.

206
00:08:54.559 --> 00:08:59.039
<v Speaker 1>So what's the secret to using promises effectively with event handlers.

207
00:08:59.559 --> 00:09:02.720
<v Speaker 2>It's about shifting our perspective. Instead of creating a promise

208
00:09:02.840 --> 00:09:06.159
<v Speaker 2>chain within the event handler, we can use observables.

209
00:09:06.360 --> 00:09:09.200
<v Speaker 1>Observables. You mentioned those earlier. They sound pretty advanced.

210
00:09:08.919 --> 00:09:12.720
<v Speaker 2>They're powerful, but the core concept is actually quite simple. Okay,

211
00:09:12.840 --> 00:09:15.399
<v Speaker 2>think of an observable like a stream of events, right,

212
00:09:15.519 --> 00:09:18.399
<v Speaker 2>like a flow of data exactly. You can subscribe to

213
00:09:18.399 --> 00:09:21.159
<v Speaker 2>an observable and react to each event that comes through

214
00:09:21.159 --> 00:09:24.799
<v Speaker 2>that stream using you guessed it promises.

215
00:09:25.000 --> 00:09:27.360
<v Speaker 1>So it's like setting up a sensor. When it detects

216
00:09:27.360 --> 00:09:30.000
<v Speaker 1>a change, it triggers a specific action.

217
00:09:30.440 --> 00:09:31.440
<v Speaker 2>Perfect analogy.

218
00:09:31.679 --> 00:09:34.720
<v Speaker 1>Okay, So observables sound like a whole other deep dive.

219
00:09:34.919 --> 00:09:37.399
<v Speaker 2>We could definitely spend a whole episode on those, but.

220
00:09:37.440 --> 00:09:39.399
<v Speaker 1>For now, let's move on to generators.

221
00:09:39.600 --> 00:09:42.879
<v Speaker 2>Generators another powerful tool in our acinc toolkit.

222
00:09:42.960 --> 00:09:44.799
<v Speaker 1>I gott admit I haven't quite wrapped my head around

223
00:09:44.799 --> 00:09:45.519
<v Speaker 1>them yet.

224
00:09:45.559 --> 00:09:48.799
<v Speaker 2>They're a really cool way to write asynchronous code that

225
00:09:48.919 --> 00:09:51.000
<v Speaker 2>looks and feels synchronous.

226
00:09:51.039 --> 00:09:53.240
<v Speaker 1>Wait, so you can write ACYNC code that looks like

227
00:09:53.240 --> 00:09:54.399
<v Speaker 1>it's running in a stray line.

228
00:09:54.480 --> 00:09:57.759
<v Speaker 2>You got it. Generators let you pause and resume execution

229
00:09:58.279 --> 00:10:00.240
<v Speaker 2>using the yield keyword, like.

230
00:10:00.240 --> 00:10:01.759
<v Speaker 1>Having a pause button for our code.

231
00:10:02.120 --> 00:10:05.480
<v Speaker 2>Exactly. You can pause the execution, wait for an asynchronous

232
00:10:05.519 --> 00:10:08.600
<v Speaker 2>operation to complete, and then resume right where you left off.

233
00:10:08.799 --> 00:10:11.080
<v Speaker 1>Okay, my mind is blown. How does that even work?

234
00:10:11.240 --> 00:10:13.720
<v Speaker 2>Imagine you have a function that needs to fetch data

235
00:10:13.759 --> 00:10:16.600
<v Speaker 2>from a server. With a generator, you can yield control

236
00:10:16.639 --> 00:10:18.120
<v Speaker 2>at the point where the request is made.

237
00:10:18.360 --> 00:10:21.799
<v Speaker 1>Okay, Then when the data is available, you can resume

238
00:10:21.840 --> 00:10:23.480
<v Speaker 1>the function right where you left off.

239
00:10:23.639 --> 00:10:26.399
<v Speaker 2>So it's like breaking down a long task into smaller,

240
00:10:26.600 --> 00:10:28.720
<v Speaker 2>more manageable chunks exactly.

241
00:10:29.200 --> 00:10:32.360
<v Speaker 1>And the best part is the code inside the generator

242
00:10:32.679 --> 00:10:34.120
<v Speaker 1>reads like a synchronous story.

243
00:10:34.600 --> 00:10:36.759
<v Speaker 2>Okay, this is starting to make sense. Good, good, But

244
00:10:36.840 --> 00:10:41.320
<v Speaker 2>how do we actually use this with real world asynchronous operations.

245
00:10:41.399 --> 00:10:43.919
<v Speaker 1>That's where promises come back into play. Okay, we can

246
00:10:43.960 --> 00:10:47.279
<v Speaker 1>create a promise that wraps the execution of the generator

247
00:10:47.600 --> 00:10:50.960
<v Speaker 1>using yield to delegate to promises for asynchronous tasks.

248
00:10:51.000 --> 00:10:52.960
<v Speaker 2>So we get the best of both worlds exactly.

249
00:10:53.480 --> 00:10:56.759
<v Speaker 1>The synchronous looking code of generators combined with the trust

250
00:10:56.799 --> 00:10:58.360
<v Speaker 1>and composability of promises.

251
00:10:58.480 --> 00:11:00.279
<v Speaker 2>Wow, that's powerful.

252
00:11:00.440 --> 00:11:00.799
<v Speaker 1>It is.

253
00:11:01.120 --> 00:11:03.080
<v Speaker 2>But what about those of us who are still supporting

254
00:11:03.120 --> 00:11:06.000
<v Speaker 2>older browsers, you know, the ones that haven't quit caught

255
00:11:06.039 --> 00:11:07.320
<v Speaker 2>up to the whole generator scene.

256
00:11:07.360 --> 00:11:08.679
<v Speaker 1>Don't worry, we got you covered.

257
00:11:08.799 --> 00:11:09.159
<v Speaker 2>Okay.

258
00:11:09.240 --> 00:11:13.080
<v Speaker 1>We can use a technique called transpiling, which basically translates

259
00:11:13.120 --> 00:11:17.240
<v Speaker 1>our fancy ES six code, including generators, into code that

260
00:11:17.360 --> 00:11:18.879
<v Speaker 1>older browsers can understand.

261
00:11:19.000 --> 00:11:22.080
<v Speaker 2>So it's like a universal translator for JavaScript exactly.

262
00:11:22.080 --> 00:11:25.960
<v Speaker 1>Okay, so we have options even when we're dealing with

263
00:11:25.159 --> 00:11:27.320
<v Speaker 1>those legacy browsers.

264
00:11:27.440 --> 00:11:28.679
<v Speaker 2>Always good to have options.

265
00:11:28.720 --> 00:11:30.759
<v Speaker 1>I feel like we've covered so much ground already.

266
00:11:30.840 --> 00:11:33.240
<v Speaker 2>We have, but we're just getting started.

267
00:11:33.360 --> 00:11:34.759
<v Speaker 1>Oh man, my brain is already full.

268
00:11:34.840 --> 00:11:37.240
<v Speaker 2>It's a lot to take in. But it's exciting stuff.

269
00:11:37.279 --> 00:11:38.879
<v Speaker 1>It is exciting, and you know what, I'm ready to

270
00:11:38.960 --> 00:11:41.799
<v Speaker 1>dive even deeper into the world of JavaScript performance.

271
00:11:41.879 --> 00:11:42.519
<v Speaker 2>Let's do it.

272
00:11:43.200 --> 00:11:47.399
<v Speaker 1>But first, a quick message from our sponsor, welcome back.

273
00:11:48.200 --> 00:11:51.600
<v Speaker 1>Before the break, we were getting into generators and promises.

274
00:11:51.960 --> 00:11:56.480
<v Speaker 1>How they can wrangle that asynchronous JavaScript all its quirks. Yeah, exactly.

275
00:11:57.080 --> 00:11:59.399
<v Speaker 1>But there's another powerful tool we've got to talk about,

276
00:11:59.600 --> 00:12:01.879
<v Speaker 1>and it's web workers. Ah.

277
00:12:02.320 --> 00:12:04.080
<v Speaker 2>Yes, web workers.

278
00:12:04.120 --> 00:12:07.600
<v Speaker 1>These things bring true parallelism to JavaScript.

279
00:12:07.720 --> 00:12:08.399
<v Speaker 2>They really do.

280
00:12:08.600 --> 00:12:11.720
<v Speaker 1>Imagine being able to run multiple pieces of code simultaneously,

281
00:12:12.080 --> 00:12:14.840
<v Speaker 1>like having a whole team of chefs in the kitchen instead.

282
00:12:14.519 --> 00:12:16.480
<v Speaker 2>Of just won much more efficient.

283
00:12:16.200 --> 00:12:18.960
<v Speaker 1>Right, No more bottlenecks at the stove, exactly. But how

284
00:12:18.960 --> 00:12:21.159
<v Speaker 1>do these webworkers actually work? Do they have their own

285
00:12:21.480 --> 00:12:23.639
<v Speaker 1>like little JavaScript universe in a way.

286
00:12:23.799 --> 00:12:27.840
<v Speaker 2>Yeah, Each webworker runs in its own isolated environment, separate

287
00:12:27.840 --> 00:12:28.720
<v Speaker 2>from the main thread.

288
00:12:28.879 --> 00:12:31.000
<v Speaker 1>So they're like independent apartments in a building.

289
00:12:31.159 --> 00:12:32.200
<v Speaker 2>That's a good way to put it.

290
00:12:32.240 --> 00:12:35.240
<v Speaker 1>They're separate, but can still, you know, communicate exactly.

291
00:12:35.279 --> 00:12:37.960
<v Speaker 2>They communicate through a system called message passing.

292
00:12:37.759 --> 00:12:39.960
<v Speaker 1>So it's like sending notes back and forth precisely.

293
00:12:40.159 --> 00:12:45.039
<v Speaker 2>They can request data, send results, coordinate their actions all

294
00:12:45.080 --> 00:12:46.679
<v Speaker 2>without stepping on each other's toes.

295
00:12:47.159 --> 00:12:51.159
<v Speaker 1>Very civilized it is. But what about data structures? Can

296
00:12:51.200 --> 00:12:54.879
<v Speaker 1>web workers access the same arrays and objects as the

297
00:12:54.919 --> 00:12:55.480
<v Speaker 1>main thread?

298
00:12:55.799 --> 00:13:01.639
<v Speaker 2>Not directly, no, okay, But there's this clever mechanism called transferable.

299
00:13:00.840 --> 00:13:03.279
<v Speaker 1>Objects transferable objects.

300
00:13:03.360 --> 00:13:06.759
<v Speaker 2>It allows them to efficiently share data instead of copying,

301
00:13:06.919 --> 00:13:09.600
<v Speaker 2>which can be slow. They transfer ownership, so.

302
00:13:09.480 --> 00:13:11.559
<v Speaker 1>It's like handing off a baton in a relay race.

303
00:13:12.039 --> 00:13:15.120
<v Speaker 2>Perfect analogy. Only one runner can hold the baton at

304
00:13:15.120 --> 00:13:17.639
<v Speaker 2>a time, but they pass it on smoothly.

305
00:13:17.399 --> 00:13:19.240
<v Speaker 1>And that's way faster than making copies.

306
00:13:19.360 --> 00:13:22.200
<v Speaker 2>Much faster, especially when you're dealing with large amounts of data.

307
00:13:22.279 --> 00:13:26.799
<v Speaker 1>Okay, webworkers sound amazing, but are there any limitations?

308
00:13:26.960 --> 00:13:31.200
<v Speaker 2>Yeah? Well, every superhero has their kryptonite, right. Webworkers don't

309
00:13:31.240 --> 00:13:33.519
<v Speaker 2>have direct access to the dom.

310
00:13:33.600 --> 00:13:36.639
<v Speaker 1>The dom, so they can't manipulate the user interface.

311
00:13:36.759 --> 00:13:41.799
<v Speaker 2>They're more like behind the scenes heroes, crunching numbers, processing data,

312
00:13:41.840 --> 00:13:43.720
<v Speaker 2>but not messing with the visual stuff.

313
00:13:43.879 --> 00:13:45.840
<v Speaker 1>Got it. They're like the engine under the hood, not

314
00:13:45.919 --> 00:13:50.039
<v Speaker 1>the flashy pain job exactly. But what about libraries in

315
00:13:50.159 --> 00:13:51.720
<v Speaker 1>external code? Can they use those?

316
00:13:51.840 --> 00:13:55.600
<v Speaker 2>Absolutely? Webworkers can use a function called import scripts to

317
00:13:55.679 --> 00:13:59.720
<v Speaker 2>load external JavaScript files. It's like giving them a whole toolbox.

318
00:13:59.279 --> 00:14:01.399
<v Speaker 1>So we could equip them for any task you got it.

319
00:14:01.600 --> 00:14:04.200
<v Speaker 1>But what about older browsers, you know, the ones that

320
00:14:04.279 --> 00:14:06.200
<v Speaker 1>haven't gotten the memo about web workers.

321
00:14:06.440 --> 00:14:10.200
<v Speaker 2>For those cases, we have polyphills polyphills. They can emulate

322
00:14:10.240 --> 00:14:13.039
<v Speaker 2>the behavior of webworkers even in those older browsers.

323
00:14:13.080 --> 00:14:15.159
<v Speaker 1>It's like finding a vintage record player that can play

324
00:14:15.200 --> 00:14:16.960
<v Speaker 1>modern digital music exactly.

325
00:14:17.039 --> 00:14:19.919
<v Speaker 2>You get the functionality, even if the browser doesn't natively

326
00:14:19.960 --> 00:14:20.480
<v Speaker 2>support it.

327
00:14:20.799 --> 00:14:24.480
<v Speaker 1>That's awesome, it is. Okay, before we move on, I've

328
00:14:24.519 --> 00:14:27.919
<v Speaker 1>heard this term thrown around SIMD. What is that all about?

329
00:14:28.240 --> 00:14:31.960
<v Speaker 2>SIMD stands for single instruction multiple data.

330
00:14:32.440 --> 00:14:33.600
<v Speaker 1>Okay, that sounds intense.

331
00:14:33.799 --> 00:14:36.480
<v Speaker 2>It's a way to perform the same operation on multiple

332
00:14:36.519 --> 00:14:37.919
<v Speaker 2>pieces of data at the same time.

333
00:14:38.159 --> 00:14:40.679
<v Speaker 1>So it's like having an assembly line of robots, each

334
00:14:40.720 --> 00:14:43.440
<v Speaker 1>one doing the same task but on a different item.

335
00:14:43.919 --> 00:14:47.799
<v Speaker 2>Perfect analogy. It's mass production for data processing, very efficient,

336
00:14:48.039 --> 00:14:52.080
<v Speaker 2>incredibly efficient, especially for computations involving large data sets.

337
00:14:52.159 --> 00:14:55.840
<v Speaker 1>Okay, so we've got web workers for task parallelism, multiple

338
00:14:55.840 --> 00:14:59.000
<v Speaker 1>workers tackling different tasks, right, and then sim and D

339
00:14:59.200 --> 00:15:03.000
<v Speaker 1>for data parallel processing multiple pieces of data at once.

340
00:15:03.120 --> 00:15:06.200
<v Speaker 2>You got it. It's all about finding the right tool

341
00:15:06.279 --> 00:15:10.080
<v Speaker 2>for the job, leveraging parallelism to boost performance.

342
00:15:10.360 --> 00:15:13.120
<v Speaker 1>This is blowing my mind. JavaScript can do so much

343
00:15:13.200 --> 00:15:14.159
<v Speaker 1>these days.

344
00:15:13.960 --> 00:15:16.120
<v Speaker 2>It really can, and it's only getting more powerful.

345
00:15:16.240 --> 00:15:18.720
<v Speaker 1>So what's next on the horizon? For JavaScript performance.

346
00:15:18.840 --> 00:15:21.559
<v Speaker 2>Well, there are some exciting proposals for new features that

347
00:15:21.600 --> 00:15:25.720
<v Speaker 2>could bring even more parallelism to JavaScript, potentially allowing for

348
00:15:25.879 --> 00:15:27.440
<v Speaker 2>direct threaded functionality.

349
00:15:27.559 --> 00:15:29.279
<v Speaker 1>Wait direct threads in JavaScript.

350
00:15:29.320 --> 00:15:32.720
<v Speaker 2>That's the idea. It's still early days, but the possibilities

351
00:15:32.759 --> 00:15:33.320
<v Speaker 2>are huge.

352
00:15:33.600 --> 00:15:36.240
<v Speaker 1>So we might be able to write truly parallel code

353
00:15:36.600 --> 00:15:39.440
<v Speaker 1>without relying on web workers or SIMD.

354
00:15:39.960 --> 00:15:40.639
<v Speaker 2>That's the goal.

355
00:15:40.679 --> 00:15:41.840
<v Speaker 1>That would be a game changer.

356
00:15:42.039 --> 00:15:45.519
<v Speaker 2>It would revolutionize how we approach JavaScript performance.

357
00:15:45.799 --> 00:15:48.679
<v Speaker 1>This deep dive has been like a crash course in

358
00:15:48.840 --> 00:15:50.080
<v Speaker 1>JavaScript optimization.

359
00:15:50.240 --> 00:15:52.039
<v Speaker 2>We've covered a lot of ground.

360
00:15:51.759 --> 00:15:55.639
<v Speaker 1>From the event loop, to concurrency, to web workers to SIMD.

361
00:15:55.960 --> 00:15:58.039
<v Speaker 1>I feel like a JavaScript performance in ninja.

362
00:15:58.120 --> 00:16:00.360
<v Speaker 2>You're well on your way, But how do.

363
00:16:00.320 --> 00:16:03.360
<v Speaker 1>We actually know if our code is performing? Well? We

364
00:16:03.440 --> 00:16:06.559
<v Speaker 1>can write all this async code, but how do we

365
00:16:06.600 --> 00:16:07.679
<v Speaker 1>measure its efficiency?

366
00:16:07.799 --> 00:16:09.080
<v Speaker 2>That's where benchmarking comes in.

367
00:16:09.159 --> 00:16:10.639
<v Speaker 1>Benchmarking okay, it's the.

368
00:16:10.639 --> 00:16:14.679
<v Speaker 2>Process of systematically measuring the performance of your code, seeing

369
00:16:14.679 --> 00:16:17.799
<v Speaker 2>how long it takes to execute certain operations. It's like

370
00:16:17.879 --> 00:16:20.279
<v Speaker 2>taking your code for a test drive on a racetrack.

371
00:16:20.480 --> 00:16:21.600
<v Speaker 1>I love that analogy.

372
00:16:21.720 --> 00:16:23.000
<v Speaker 2>You see how fast it can go.

373
00:16:23.399 --> 00:16:26.200
<v Speaker 1>So how do we actually benchmark our JavaScript code? Do

374
00:16:26.240 --> 00:16:27.879
<v Speaker 1>we need special equipment.

375
00:16:27.639 --> 00:16:30.840
<v Speaker 2>Not necessarily. For simple tests, you can use the built

376
00:16:30.840 --> 00:16:34.799
<v Speaker 2>inconsole dot time and console dot time end methods.

377
00:16:34.879 --> 00:16:37.000
<v Speaker 1>Okay, so we can get a quick snapshot using the

378
00:16:37.039 --> 00:16:38.120
<v Speaker 1>console exactly.

379
00:16:38.200 --> 00:16:40.519
<v Speaker 2>It's like using a stopwatch to time your code.

380
00:16:40.639 --> 00:16:43.240
<v Speaker 1>But I'm guessing there are more sophisticated tools out there

381
00:16:43.279 --> 00:16:44.559
<v Speaker 1>for serious benchmarking.

382
00:16:44.840 --> 00:16:47.919
<v Speaker 2>Absolutely. If you need more detailed measurements, you can use

383
00:16:47.960 --> 00:16:50.080
<v Speaker 2>libraries like benchmark dot js.

384
00:16:50.200 --> 00:16:51.679
<v Speaker 1>Benchmark dot js okay.

385
00:16:51.879 --> 00:16:55.159
<v Speaker 2>It allows you to run multiple tests, collect data, even

386
00:16:55.279 --> 00:16:56.759
<v Speaker 2>calculate the margin of error.

387
00:16:56.840 --> 00:16:58.919
<v Speaker 1>Wow, margin of error. We're getting serious now.

388
00:16:59.120 --> 00:17:01.279
<v Speaker 2>It's all about getting and reliable data so you can

389
00:17:01.279 --> 00:17:02.399
<v Speaker 2>make informed decisions.

390
00:17:02.919 --> 00:17:06.079
<v Speaker 1>So let's say we've run our benchmarks, we have some data.

391
00:17:06.599 --> 00:17:10.200
<v Speaker 1>Now comes the fun part tuning. Where do we even begin.

392
00:17:10.599 --> 00:17:13.920
<v Speaker 2>The first step is to identify the bottlenecks, the parts

393
00:17:13.920 --> 00:17:15.720
<v Speaker 2>of your code that are slowing things down.

394
00:17:16.119 --> 00:17:18.079
<v Speaker 1>So it's like finding the weak link in a chain.

395
00:17:18.319 --> 00:17:21.720
<v Speaker 2>Precisely. Once you've found the bottlenecks, you can start exploring

396
00:17:21.759 --> 00:17:23.400
<v Speaker 2>different optimization strategies.

397
00:17:23.480 --> 00:17:25.839
<v Speaker 1>It's like being a code detective searching for clues to

398
00:17:25.880 --> 00:17:27.319
<v Speaker 1>improve performance.

399
00:17:26.960 --> 00:17:29.680
<v Speaker 2>Exactly, And just like a good detective, you need the

400
00:17:29.759 --> 00:17:31.039
<v Speaker 2>right tools and techniques.

401
00:17:31.640 --> 00:17:35.200
<v Speaker 1>So what are some common strategies for optimizing JavaScript code.

402
00:17:35.400 --> 00:17:38.559
<v Speaker 2>One common approach is to reduce the number of function calls.

403
00:17:38.680 --> 00:17:39.839
<v Speaker 1>Okay. Function calls can.

404
00:17:39.759 --> 00:17:43.480
<v Speaker 2>Be expensive, they can be, so minimizing their use can

405
00:17:43.480 --> 00:17:45.079
<v Speaker 2>often lead to performance gains.

406
00:17:45.160 --> 00:17:48.079
<v Speaker 1>So it's all about streamlining the flow of execution.

407
00:17:48.039 --> 00:17:50.559
<v Speaker 2>Exactly, make it as smooth as possible.

408
00:17:50.920 --> 00:17:53.799
<v Speaker 1>What about object creation? I've heard that creating lots of

409
00:17:53.839 --> 00:17:55.400
<v Speaker 1>objects can slow things down.

410
00:17:55.640 --> 00:17:59.680
<v Speaker 2>You're right. Object creation, especially for large or complex objects,

411
00:17:59.759 --> 00:18:00.960
<v Speaker 2>can be a performance hit.

412
00:18:01.160 --> 00:18:03.839
<v Speaker 1>Okay, So minimize unnecessary object creation.

413
00:18:03.960 --> 00:18:05.240
<v Speaker 2>That's a good rule of thumb.

414
00:18:05.200 --> 00:18:09.279
<v Speaker 1>Got it. Reduce objects, streamline functions, check and check. But

415
00:18:09.319 --> 00:18:12.920
<v Speaker 1>what about arrays? Any tips for optimizing code that works

416
00:18:13.119 --> 00:18:13.680
<v Speaker 1>with a RaSE?

417
00:18:13.839 --> 00:18:16.440
<v Speaker 2>Absolutely? For example, when you're looping through an array, it's

418
00:18:16.480 --> 00:18:19.759
<v Speaker 2>often more efficient to cache the length of the array

419
00:18:19.839 --> 00:18:22.640
<v Speaker 2>rather than recalculating it on each iteration.

420
00:18:22.960 --> 00:18:25.680
<v Speaker 1>Ah. So it's like remembering how many ingredients you need

421
00:18:25.720 --> 00:18:27.680
<v Speaker 1>instead of recounting them every time you add something to

422
00:18:27.720 --> 00:18:27.960
<v Speaker 1>the bowl.

423
00:18:28.119 --> 00:18:30.240
<v Speaker 2>Exactly. It's a little shortcut for your code.

424
00:18:30.400 --> 00:18:32.599
<v Speaker 1>Very clever. I like it. Good, good, Okay. What about

425
00:18:32.640 --> 00:18:36.799
<v Speaker 1>async specific optimizations? Any things to keep in mind when

426
00:18:36.839 --> 00:18:40.160
<v Speaker 1>working with promises, generators, web workers definitely.

427
00:18:40.759 --> 00:18:44.680
<v Speaker 2>When working with promises, it's generally best to resolve or

428
00:18:44.720 --> 00:18:47.359
<v Speaker 2>reject them as soon as possible. No need to.

429
00:18:47.279 --> 00:18:50.400
<v Speaker 1>Delay, okay, So keep those promises flowing exactly.

430
00:18:50.839 --> 00:18:54.839
<v Speaker 2>And with generators, remember that each yield represents a potential

431
00:18:54.920 --> 00:18:57.759
<v Speaker 2>pause point. Use them strategically, like.

432
00:18:57.759 --> 00:18:59.200
<v Speaker 1>Hitting the pause button on a movie.

433
00:18:59.279 --> 00:19:01.720
<v Speaker 2>Right. You don't want to pause every few seconds, got it?

434
00:19:02.079 --> 00:19:06.359
<v Speaker 1>Use yield strategically and keep those promises moving precisely. But earlier,

435
00:19:06.400 --> 00:19:09.880
<v Speaker 1>you mentioned that different JavaScript engines might optimize code in

436
00:19:09.880 --> 00:19:10.519
<v Speaker 1>different ways.

437
00:19:10.640 --> 00:19:11.200
<v Speaker 2>That's true.

438
00:19:11.440 --> 00:19:13.920
<v Speaker 1>Does that mean we need to write code that's specifically

439
00:19:13.960 --> 00:19:15.279
<v Speaker 1>tailored to each engine?

440
00:19:15.400 --> 00:19:18.319
<v Speaker 2>Ideally we want our code to perform well everywhere, But

441
00:19:18.359 --> 00:19:21.160
<v Speaker 2>the reality is different engines have their own quirks.

442
00:19:21.480 --> 00:19:23.200
<v Speaker 1>It's like trying to write a song that sounds good

443
00:19:23.200 --> 00:19:25.880
<v Speaker 1>on both a grand piano and a ukulele exactly.

444
00:19:26.039 --> 00:19:27.599
<v Speaker 2>So how do we strike that balance?

445
00:19:27.960 --> 00:19:30.599
<v Speaker 1>How do we write code that's universally optimized?

446
00:19:30.759 --> 00:19:34.559
<v Speaker 2>Start with general optimization principles that apply across all engines,

447
00:19:34.680 --> 00:19:37.799
<v Speaker 2>and then if you have specific bottlenecks, you can use

448
00:19:37.880 --> 00:19:41.440
<v Speaker 2>feature detection trure detection okay, to identify the current engine

449
00:19:41.559 --> 00:19:44.400
<v Speaker 2>and apply targeted optimizations, so.

450
00:19:44.359 --> 00:19:47.200
<v Speaker 1>We're gathering intel on the environment before we deploy our code.

451
00:19:47.319 --> 00:19:50.559
<v Speaker 2>Exactly. It's all about being adaptable, understanding the nuances of

452
00:19:50.599 --> 00:19:52.000
<v Speaker 2>different JavaScript environments.

453
00:19:52.000 --> 00:19:55.200
<v Speaker 1>Okay, that makes senseick, But there's one more optimization concept

454
00:19:55.200 --> 00:19:58.119
<v Speaker 1>I want to talk about. What's that pail call optimization?

455
00:19:58.519 --> 00:20:04.000
<v Speaker 2>Ah y, Yes. TCO a powerful technique for improving the

456
00:20:04.039 --> 00:20:05.799
<v Speaker 2>performance of recursive functions.

457
00:20:06.000 --> 00:20:08.119
<v Speaker 1>Cursive functions those are the ones that call themselves, right,

458
00:20:08.200 --> 00:20:11.519
<v Speaker 1>that's right, But I've heard they can be dangerous because

459
00:20:11.519 --> 00:20:12.839
<v Speaker 1>of stack overflow errors.

460
00:20:13.079 --> 00:20:16.480
<v Speaker 2>They can be If a recursive function calls itself too

461
00:20:16.480 --> 00:20:18.720
<v Speaker 2>many times, it can fill up the call stack and

462
00:20:18.759 --> 00:20:21.519
<v Speaker 2>crash the program. That sounds bad, it can be, But

463
00:20:21.640 --> 00:20:26.160
<v Speaker 2>TCO prevents this by optimizing how recursive functions are executed.

464
00:20:26.319 --> 00:20:28.960
<v Speaker 1>So TCO is like a safety net for recursive functions.

465
00:20:29.079 --> 00:20:32.039
<v Speaker 2>You could say that in a nutshell, when a function

466
00:20:32.119 --> 00:20:34.880
<v Speaker 2>call is in the tail position, meaning it's the last

467
00:20:34.880 --> 00:20:38.960
<v Speaker 2>operation performed by the function, the engine can reuse the

468
00:20:39.039 --> 00:20:41.799
<v Speaker 2>existing stack frame instead of creating a new one.

469
00:20:41.960 --> 00:20:44.039
<v Speaker 1>So it's like recycling those.

470
00:20:43.880 --> 00:20:47.799
<v Speaker 2>Stack frames exactly, saves memory and improves performance.

471
00:20:47.880 --> 00:20:50.440
<v Speaker 1>That's very clever. TCO sounds like a must have for

472
00:20:50.559 --> 00:20:52.119
<v Speaker 1>any serious recursive function.

473
00:20:52.400 --> 00:20:56.039
<v Speaker 2>It is, and luckily ES six made TCO a requirement,

474
00:20:56.359 --> 00:20:58.640
<v Speaker 2>so modern JavaScript engines should all support it.

475
00:20:58.839 --> 00:21:01.599
<v Speaker 1>That's great. News is okay. We've covered a ton of

476
00:21:01.599 --> 00:21:07.119
<v Speaker 1>ground here benchmarking, tuning different JavaScript engines TCO. My head

477
00:21:07.160 --> 00:21:07.759
<v Speaker 1>is spinning.

478
00:21:07.880 --> 00:21:09.799
<v Speaker 2>That's a lot to take in. But you're doing great.

479
00:21:09.839 --> 00:21:12.079
<v Speaker 1>I'm starting to feel like I can actually write JavaScript

480
00:21:12.079 --> 00:21:13.160
<v Speaker 1>code that performs well.

481
00:21:13.319 --> 00:21:16.559
<v Speaker 2>You're well on your way. Remember, optimizing JavaScript performance is

482
00:21:16.599 --> 00:21:19.559
<v Speaker 2>an ongoing journey. There's always more to learn and explore.

483
00:21:19.720 --> 00:21:23.039
<v Speaker 1>It's a marathon, not a sprint exactly. But before we

484
00:21:23.079 --> 00:21:25.200
<v Speaker 1>get too carried away with all this performance talk, I

485
00:21:25.240 --> 00:21:27.359
<v Speaker 1>want to shift gears a bit and talk about something

486
00:21:27.400 --> 00:21:29.839
<v Speaker 1>equally important. Readability.

487
00:21:30.200 --> 00:21:34.559
<v Speaker 2>Ah. Yes, readability just as important as performance, because what.

488
00:21:34.559 --> 00:21:37.359
<v Speaker 1>Good is super fast code if no one can understand it?

489
00:21:37.559 --> 00:21:43.160
<v Speaker 2>Exactly? Writing readable code is crucial for collaboration, maintainability, and

490
00:21:43.279 --> 00:21:44.160
<v Speaker 2>your own sanity.

491
00:21:44.720 --> 00:21:48.640
<v Speaker 1>I've definitely encountered some code that felt like deciphering ancient hieroglyphics.

492
00:21:48.720 --> 00:21:49.519
<v Speaker 2>We have all been there.

493
00:21:49.640 --> 00:21:52.000
<v Speaker 1>It's like, what was I thinking when I wrote this?

494
00:21:52.759 --> 00:21:56.319
<v Speaker 2>But writing readable code is not just about avoiding confusion.

495
00:21:56.480 --> 00:21:59.200
<v Speaker 2>It's about creating code that's enjoyable to work with.

496
00:21:59.319 --> 00:22:01.759
<v Speaker 1>Okay, making the code a pleasure.

497
00:22:01.400 --> 00:22:06.319
<v Speaker 2>To read, exactly, code that's clear, concise, and expresses your

498
00:22:06.319 --> 00:22:09.200
<v Speaker 2>intent in a way that others can easily understand.

499
00:22:09.680 --> 00:22:11.559
<v Speaker 1>So how do we actually achieve that? How do we

500
00:22:11.599 --> 00:22:17.680
<v Speaker 1>write code that's both efficient and elegant? And we're back.

501
00:22:18.200 --> 00:22:20.119
<v Speaker 1>We were just talking about how important it is to

502
00:22:20.160 --> 00:22:23.799
<v Speaker 1>write readable code, code does not just functional, but actually

503
00:22:23.880 --> 00:22:24.640
<v Speaker 1>enjoyable to.

504
00:22:24.599 --> 00:22:26.799
<v Speaker 2>Work with, right, Because we all want our code to

505
00:22:26.799 --> 00:22:29.240
<v Speaker 2>be elegant, but let's face it, we also want to

506
00:22:29.359 --> 00:22:31.799
<v Speaker 2>squeeze every ounce of performance out of our JavaScript.

507
00:22:31.920 --> 00:22:34.880
<v Speaker 1>Absolutely, we're all about speed. But how do we find

508
00:22:34.880 --> 00:22:39.599
<v Speaker 1>that balance between writing beautiful code and making it lightning fast?

509
00:22:39.680 --> 00:22:42.359
<v Speaker 2>It's a constant juggling act, and I think sometimes we

510
00:22:42.440 --> 00:22:46.079
<v Speaker 2>get caught up in what we call micro optimizations. You know,

511
00:22:46.119 --> 00:22:49.000
<v Speaker 2>those tiny tweaks that promise a performance boost, but do

512
00:22:49.039 --> 00:22:50.519
<v Speaker 2>they actually make a real difference.

513
00:22:50.640 --> 00:22:52.799
<v Speaker 1>Oh, I've definitely been down that rabbit hole before, like

514
00:22:52.920 --> 00:22:55.680
<v Speaker 1>obsessing over whether to use plus plus A or A

515
00:22:55.759 --> 00:22:56.440
<v Speaker 1>plus plus.

516
00:22:56.519 --> 00:22:57.519
<v Speaker 2>Yeah, we've all been there.

517
00:22:57.640 --> 00:22:58.920
<v Speaker 1>Did it really matter in the end?

518
00:22:59.240 --> 00:23:02.640
<v Speaker 2>Probably not. It's easy to get fixated on those benchmarks

519
00:23:02.680 --> 00:23:06.799
<v Speaker 2>that focus on isolated operations. But those tiny differences they

520
00:23:06.839 --> 00:23:09.559
<v Speaker 2>often become insignificant when you look at the whole picture

521
00:23:09.559 --> 00:23:10.839
<v Speaker 2>of a complex application.

522
00:23:11.680 --> 00:23:14.119
<v Speaker 1>It's like rearranging the furniture in your house to save

523
00:23:14.160 --> 00:23:18.119
<v Speaker 1>a few steps. Technically more efficient, but does it really change.

524
00:23:17.960 --> 00:23:22.720
<v Speaker 2>Your life exactly. Context is key. Optimize for clarity and

525
00:23:22.759 --> 00:23:26.880
<v Speaker 2>maintainability first. Then if you have performance bottlenecks, you can

526
00:23:26.880 --> 00:23:30.319
<v Speaker 2>look at those micro optimizations. Right, don't sweat the small

527
00:23:30.359 --> 00:23:32.480
<v Speaker 2>stuff exactly, focus on the big picture.

528
00:23:32.599 --> 00:23:35.559
<v Speaker 1>But even when we are focused on those bigger optimizations,

529
00:23:35.559 --> 00:23:39.279
<v Speaker 1>we have to remember that different JavaScript engines might optimize

530
00:23:39.319 --> 00:23:40.160
<v Speaker 1>things differently.

531
00:23:40.799 --> 00:23:44.359
<v Speaker 2>That's true. The javascriptspec gives engines a lot of leeway

532
00:23:44.680 --> 00:23:47.640
<v Speaker 2>in how they optimize code. It's like having different chefs

533
00:23:47.720 --> 00:23:50.759
<v Speaker 2>using the same recipe but maybe adding their own personal flare.

534
00:23:51.359 --> 00:23:54.359
<v Speaker 1>So our code might perform differently depending on the engine

535
00:23:54.400 --> 00:23:58.240
<v Speaker 1>it's running on, even if we follow the same best practices.

536
00:23:58.079 --> 00:24:02.640
<v Speaker 2>Yep, exactly. Some times what was considered an optimization, well

537
00:24:03.359 --> 00:24:04.839
<v Speaker 2>it's not the best approach anymore.

538
00:24:05.039 --> 00:24:08.279
<v Speaker 1>You mean, like what worked yesterday doesn't necessarily work today.

539
00:24:08.519 --> 00:24:12.119
<v Speaker 2>Right. For example, years ago, using a ray dot joined

540
00:24:12.160 --> 00:24:15.079
<v Speaker 2>to put strings together was generally faster than using the

541
00:24:15.079 --> 00:24:20.039
<v Speaker 2>plus operator. Interesting, But then JavaScript engines evolved got smarter.

542
00:24:20.240 --> 00:24:24.039
<v Speaker 2>They did, and they introduced optimizations for the plus operator,

543
00:24:24.559 --> 00:24:27.359
<v Speaker 2>and it became more efficient. So the landscape shifted.

544
00:24:27.839 --> 00:24:28.920
<v Speaker 1>So what's the takeaway here?

545
00:24:29.039 --> 00:24:32.960
<v Speaker 2>Be adaptable, stay informed about what's going on with JavaScript engines.

546
00:24:33.359 --> 00:24:36.160
<v Speaker 2>What's best practiced today might not be tomorrow.

547
00:24:36.319 --> 00:24:38.160
<v Speaker 1>Got to stay ahead of the curve exactly.

548
00:24:38.400 --> 00:24:40.680
<v Speaker 2>But there's another interesting thing about these engines.

549
00:24:40.880 --> 00:24:41.559
<v Speaker 1>Oh, what's that.

550
00:24:41.759 --> 00:24:44.920
<v Speaker 2>They don't always execute code in the exact order it's written.

551
00:24:45.000 --> 00:24:47.400
<v Speaker 1>Wait, hold on, they could just rearrange my code.

552
00:24:47.119 --> 00:24:50.960
<v Speaker 2>Well, not rearrange randomly, but optimize. Okay, the engine can

553
00:24:51.039 --> 00:24:54.880
<v Speaker 2>analyze your code figure out if reordering some statements would

554
00:24:54.880 --> 00:24:58.720
<v Speaker 2>improve performance without changing the outcome, like a super efficient editor.

555
00:24:58.920 --> 00:25:01.440
<v Speaker 1>So they're making my code better without messing with the

556
00:25:01.480 --> 00:25:04.440
<v Speaker 1>meaning exactly. Okay, I can live with that. Good. So

557
00:25:04.480 --> 00:25:06.599
<v Speaker 1>we need to like trust the engine, but also be

558
00:25:06.640 --> 00:25:08.720
<v Speaker 1>aware of this reordering thing exactly.

559
00:25:08.960 --> 00:25:11.599
<v Speaker 2>Now, speaking of optimization, there's one more concept I want

560
00:25:11.640 --> 00:25:13.839
<v Speaker 2>to bring up, tail call optimization.

561
00:25:14.279 --> 00:25:17.160
<v Speaker 1>Tail call optimization or TCO as.

562
00:25:17.039 --> 00:25:20.359
<v Speaker 2>The cool kids call it, right, it can dramatically improve

563
00:25:20.400 --> 00:25:22.200
<v Speaker 2>the performance of recursive functions.

564
00:25:22.279 --> 00:25:24.680
<v Speaker 1>Okay, remind me recursive functions those are the ones that

565
00:25:24.720 --> 00:25:25.960
<v Speaker 1>call themselves.

566
00:25:25.640 --> 00:25:27.720
<v Speaker 2>That's right, but they can be tricky because of those

567
00:25:27.759 --> 00:25:29.559
<v Speaker 2>pesky stack overflow errors.

568
00:25:29.599 --> 00:25:31.920
<v Speaker 1>Yeah, those can be a real headache. So TCO helps

569
00:25:31.960 --> 00:25:33.279
<v Speaker 1>prevent those exactly.

570
00:25:33.640 --> 00:25:37.319
<v Speaker 2>With TCO, when a function call is in the tail position,

571
00:25:37.599 --> 00:25:40.880
<v Speaker 2>meaning it's the very last thing the function does, the

572
00:25:40.920 --> 00:25:42.839
<v Speaker 2>engine can optimize how it runs.

573
00:25:42.920 --> 00:25:45.079
<v Speaker 1>So instead of creating a brand new stack frame every

574
00:25:45.119 --> 00:25:48.720
<v Speaker 1>time the function calls itself, it reuses the existing.

575
00:25:48.319 --> 00:25:49.920
<v Speaker 2>One precisely like recycling.

576
00:25:50.200 --> 00:25:53.720
<v Speaker 1>Very efficient, very clever. So TCO definitely something to keep

577
00:25:53.720 --> 00:25:55.640
<v Speaker 1>in mind when working with recursive functions.

578
00:25:55.960 --> 00:25:59.920
<v Speaker 2>It is, and luckily modern jobscript engines all support it.

579
00:26:00.079 --> 00:26:02.720
<v Speaker 1>Well, that's a relief, it is. It feels like we've

580
00:26:02.759 --> 00:26:06.039
<v Speaker 1>covered a whole universe of JavaScript performance in this deep dive.

581
00:26:06.400 --> 00:26:11.480
<v Speaker 1>From the event loop and concurrency to promises and generators,

582
00:26:11.839 --> 00:26:16.480
<v Speaker 1>web workers, benchmarking, tuning, and now TCO.

583
00:26:16.799 --> 00:26:18.119
<v Speaker 2>We've been on quite a journey.

584
00:26:18.319 --> 00:26:20.599
<v Speaker 1>My brain is overflowing, but in a good way.

585
00:26:20.759 --> 00:26:22.880
<v Speaker 2>It's a lot to absorb, but the key is to

586
00:26:22.920 --> 00:26:25.079
<v Speaker 2>remember that this is just the beginning, right.

587
00:26:24.960 --> 00:26:27.200
<v Speaker 1>There's always more to learn and explore in the world's

588
00:26:27.200 --> 00:26:27.880
<v Speaker 1>of javascripts.

589
00:26:27.920 --> 00:26:31.839
<v Speaker 2>Exactly, keep experimenting, keep pushing those boundaries and most importantly,

590
00:26:31.960 --> 00:26:32.680
<v Speaker 2>have fun with it.

591
00:26:32.720 --> 00:26:35.319
<v Speaker 1>Couldn't have set it better myself, so to our listeners,

592
00:26:35.559 --> 00:26:38.359
<v Speaker 1>thanks for joining us on this deep dive. Keep learning,

593
00:26:38.480 --> 00:26:41.759
<v Speaker 1>keep coding, and keep that JavaScript running smooth and fast.
