Shadowing Practice: Next.js 16.3 got good (if you care) - Learn English Speaking with Video

Creating lesson...
1
So in the last two weeks, I was at Next.js Night London, and I was at Next.js Night in Amsterdam.
2
And at both of those events, I got to see members of the Vercel and Next.js team show off Next 16.3.
3
And admittedly, I hadn't looked at Next in quite a while.
4
I think my last real busy experience with Next was back in the day
5
when everything was cached and there was sort of nothing you could do about it.
6
But seeing how it's changed, and I saw the launch of cache components, I think, at last year's Next.js conference as well and seeing where the 16.3 preview is going.
7
It's really cool to see the emphasis on declarative cache controls over everything, which is excellent.
8
So you can be really specific about where you want that caching to be.
9
And also just to see how much dedication the team has to making sure that your application is fast.
10
And that's what the topic of my talk ended up being about.
11
I've been thinking a lot recently with my job at PlanetScale about reducing people's egress.
12
That is the amount of data that is being fetched from your database.
13
and I'll go through that in my talk, which I'm going to present here in this video.
14
But the reason I've titled this video what I have is like Next.js is back if you care, is that you need to have a degree of care to make sure that your application is really,
15
really great because the team building Next.js, it's very clear they desperately care about making sure your application loads really quickly
16
and it's as smooth and as good an experience as possible.
17
But while you've never been able to build apps faster than ever and you can build NextGest apps so quickly, you can build any kind of app so quickly now,
18
it's still not going to be excellent if you don't really care.
19
The agent's not going to care for you.
20
So it's about you knowing exactly what you want from your application and what is making it slow.
21
And if you don't know what's making it slow, I think that's probably what I'm most excited about with some of those updates.
22
And I want to show this off first.
23
This is the application that I chose to build for my talk at both of those nights.
24
And it's a NextGest application.
25
It's It's kind of like a block editor, like a rich text editing sort of experience like you'd have.
26
It's backed by Postgres database.
27
I've got a list of pages on the left-hand side that I'm working on, and I've got a title here and some blocks to be writing there.
28
But this insights thing, this was instant insights.
29
This is really cool to see is that if your app isn't as fast and as smooth as it could be, Next.js will now tell you in development mode, and that's really cool.
30
And there's all these different ways to copy prompts here to say, hey, would you rather stream this in and have a skeleton?
31
Or would you rather cache this if you know the parameters ahead of time?
32
Or are you just okay with this holding up rendering on the page?
33
And perhaps you can set a way to say, hey, ignore that.
34
And again, in a really declarative way, this is what I want my code to do.
35
And being declarative, a word I'm going to use a lot in this talk, as well as the word cache, definitely I'm going to wear that out.
36
It's good for a number of reasons.
37
It's good for you especially to know sort of what you want the code to do.
38
But it's good for agents as well the more hints
39
that you can leave through your code base of how you want things done, the better agents will work with that code.
40
And they'll continue to implement those patterns if they see why those things are implemented.
41
They'll only fetch the data that they need when they know what data the application uses.
42
So being very clear about your requirements has always been useful for humans.
43
It's especially useful for agents as well.
44
So without any further ado, I mean, what I'll do is I'll go back to cursor here and I'll put this code back in.
45
I had really optimized this app.
46
So I had thought before I built it.
47
And then I went to the first next year I was in Amsterdam and saw them show off these instant insights, upgraded to the preview and it spotted that this was an optimization that I could have made.
48
And so now the app loads really, really, really fast, which is excellent, faster than it did before.
49
So let's go and have a look at the talk.
50
So the talk that I gave was titled Faster and Cheaper.
51
And that's kind of the typical PlanetScale experience when you come and grab a PlanetScale database.
52
But this is the experience that all of your applications should have um
53
so at best
54
when you're working with ai development the code works right like that's kind of the baseline
55
that and and that's what you really want
56
and i know a lot of people have made an argument
57
that taste is going to be the differentiator and i'm not sure
58
that i agree with that personally because you know and i know
59
that there's a lot of applications and services
60
that are they dominate their sector they dominate their industry
61
and yet they're quite terrible applications we all have worked with those applications we didn't want to before
62
but that's just what the sector uses so it's great
63
that the code works
64
but ideally i hope this is why you would go to a thing like next.js night
65
and this is why the people who build next.js are building it the way they are
66
and and that's why you're watching this video is
67
because you want to make better things um ideally your application's fast
68
and it works really well and it's very smooth that's that's the that's the better state
69
but but it only gets there if you care.
70
And at worst, and that's what I really want to highlight in this video today, is at worst, if your application's bad, it's not just slow, but it can cost you money.
71
If your application is fetching too much and too often, you're going to run up your egress rates.
72
And so like your CPU is going to work too hard.
73
You're going to fetch too much data too often.
74
And that can add up when you hit scale.
75
You don't want to, you know, the thing used to be about, if I hit Hacker News, I don't want my website to go down.
76
You know, I think that's less of a likelihood now.
77
But if for whatever reason, you know, your app hits wild popularity and all of those unoptimized fetches you were doing, now they quickly add up.
78
You blast through your egress quota.
79
It can cost you money.
80
So it's important to look at slop for both making your application faster, but also make sure it doesn't cost you money.
81
And prematurely optimizing is not a bad thing in this instance.
82
You don't want to wait until you get that scary bill.
83
Oh, no, you hit scale.
84
Now it's cost you a lot of money.
85
You don't have to wait for that moment as a forcing function to fix these things.
86
You fix them in advance, you'll get a better application sooner.
87
So I wanted to illustrate a few patterns that are really worth keeping an eye on when it comes to developing.
88
So you know and I know we don't write the code anymore, right?
89
But there are still patterns in code that as of this moment, agents will typically get wrong or bad.
90
And this is what I really want to highlight here at the moment is
91
that I'm not saying here's a code snippet you should copy, but rather here's the sorts of things that agents will do unsupervised.
92
And you could take like this video or my blog post
93
that I wrote about this on the PlanetScale blog and give it to your agent and say, hey, just check out these patterns.
94
And it'll, you know, do the job of double checking.
95
But I think it's worth building your personal context to know what to look for, to make sure the apps that you're building are really, really good.
96
And so here on the left hand side, like just having a query function from here's like I'm using
97
drizzle orm you know just having a query that's going to
98
select every column from a particular row that's going to fetch way too much
99
or worse again because it's imperative you're not saying exactly what you need it's unclear to the agent
100
and to humans what you're actually using in the application from
101
that row in the database
102
so returning only what you use there on the right hand
103
side that's really important for both things to limit the amount of content
104
that you're pulling and also to make it very clear what you need
105
because you know in this instance get posts that function is probably pulling this post list on the left-hand side.
106
And I don't need to pull in all of the content.
107
If I was grabbing everything, I'd be grabbing this whole content column, which is a huge JSONB column.
108
So you can imagine how much slower it'd make this query
109
to fetch all of those every time I load the list of posts.
110
I don't need to do that.
111
I only want what I need.
112
So you also want to make sure that you're returning less data.
113
So this is an instance where writing which is ingress can actually become egress.
114
And that is to make sure that, if your function has this method on the end,
115
this returning one, which I was only writing another demo application today and it did this exact thing.
116
You know, I was writing something to the database and it just returned everything.
117
And this will actually return more than you actually wrote.
118
So if I was to just like update the post and update the title, but say, hey, return everything from that row.
119
Again, it could be returning the entire JSON body of that big content area, which again, it's not what I want.
120
So only return what you need if you need to return anything at all.
121
Agents will typically write too much code.
122
And so they'll return the whole row, even if you weren't using it in the application.
123
So you want to fetch less often.
124
And that's where we start to use these caching functions.
125
You might have different frameworks, different places to cache.
126
Next.js's caching controls are really, really great.
127
And here you can see this declarative nature of them.
128
So first of all, when you write use cache there, that's part of that cache components.
129
That is a signal to Next.js.
130
I want you to cache this function invocation and the parameters that it has.
131
And then you give it a name.
132
So you write this cache tag here.
133
You say, I'm using this human readable identifier to say that
134
if I ever want to invalidate this cache and force a revalidation of it, then I just need to invalidate this particular tag.
135
And so that's what the relationship of these two things.
136
That one, top one, use for cache, that's for Next.js, cache tag, that's for you.
137
And so to have that same getPost function from before, but then have a cached version of it, that means that I can still fetch on demand when I want to have fresh data,
138
but I can fetch a cached version of it, which is going to be much faster as well.
139
And this can be dynamic too.
140
So if I'm going to get the post by the slug, then I can use a cache tag there that is dynamic in that it's using just this unique value,
141
which means I can still invalidate just that page and just that fetch in the cache.
142
So we want to invalidate and refresh on demand as well.
143
So there's instances where you might want to revalidate where it's
144
okay to leave stale data on the page for a short amount of time.
145
There's going to be instances where that is definitely not okay.
146
So for example, deleting a post from the database, I want to update this tag to say, hey, I've deleted this post.
147
Let's get rid of that immediately out of the cache as well as out of the database.
148
So you get controls on when to set up that cache, but also when to tear it down.
149
It's important too to limit the blast radius of updates.
150
So for example, not all updates are created equal.
151
If we go back to my document here, making a change to this content area, that is going to send quite a large transfer over the wire.
152
So I don't want to have to update the entire page here and all these layouts
153
because I'm only updating that content area there where, for example, if I'm going to edit just this title section, I've got a different function there because that is going to need to invalidate this list.
154
And so that list is going to need to be refreshed.
155
So that means that when I'm making changes within this content area here, I'm not forcing a revalidation or re-rendering of the post list on the left-hand side.
156
But when I do need to force that rendering, I can change this title here.
157
And so that's using a different function.
158
So splitting up those functions to perform those edits can be really important just to make sure
159
that those changes and the impact of them ripple through as little of the application as possible.
160
So it's important too to fetch in priority order.
161
So not all content on the page needs to be seen at the same time.
162
So here on the left-hand side, if I'm loading the URL to load this particular page, this content area is the primary thing that I want to see first and the list on the left-hand side,
163
I can suspend that and stream that in later.
164
I don't mind.
165
I could put a loading spinner there, but personally, I hate loading spinners and fetches from PlanetScale should be so quick that you really need to see them anyway.
166
But yeah, I've set this up that I've actually suspended this list of posts here.
167
But this content area on the right-hand side is actually server-side rendered.
168
And so what I've done here, because this editor here, this editing block editor component that I've got,
169
it's called Portable Text and it has a rendering component as well as an editing component.
170
Now the editing component is super heavy and very interactive.
171
So it has to be a client component, but I've got a server rendered version of it
172
and you might see a flash for a second there where it's like half opacity and then it sort of fades in.
173
And I did that deliberately because I wanted the page to load incredibly quickly.
174
We're doing the smallest possible piece amount of work on the server side to render that as quickly as possible.
175
But as soon as it can become interactive, it is.
176
So we're sort of fetching and rendering in priority order.
177
I think I've stolen the next slide.
178
Yeah, rendering in priority order.
179
So that's what I was sort of saying there is to have that sort of static content rendering.
180
And then as soon as the editor is ready, that gets rendered in there, you know, where it's live.
181
And also I've got some import things there to say that, hey, the editor should not be part of that server side rendered bundle.
182
So I'm keeping that as small as possible on the server
183
and then only bringing it into the client side when I need it.
184
It's also important to cache as few keys as possible, particularly when it comes to user input.
185
So we have those dynamic tags for caching, and that's excellent.
186
But when it comes to user input that's going to result in a cache, we want to reduce the number of potential caches that we can create.
187
So, for example, here, if I was going to change the weather selector here, you know, if I'm searching for London or, you know, London in all caps with spaces either side of it,
188
those shouldn't end up in different cache entries.
189
You know, we can normalize that, make it all lowercase, trim off any white space, and that's going to be useful.
190
So just to, I mean, that's just one very specific example, but in any way where you can reduce the number of tags that are going to return the same data, that's incredibly important.
191
And especially again, when it comes to user input.
192
And fetching more or less often, you do get controls in Next.js as well over the lifetime of the cache too.
193
So things like weather updates, I'd only wanna cache it for a few minutes at the most because that can change quite variably, but there are other things that could last for hours and they're likely going to be okay.
194
So you're in control of the length of time, and you can also even change the settings in the next
195
config to sort of create your own named values for when things are cached and when they are revalidated, which is really cool again.
196
And again, it's just all these controls that you get to put in your code so agents can read them.
197
It's really, really neat.
198
And then caching about streaming children.
199
This was a sort of important thing when building this demo as well, is that this component here, because this has to do an asynchronous lookup to fetch the weather,
200
I didn't want loading those components to hold up that server-side rendered data fetch.
201
So the server-ended version, it uses a cached version of this data if it has access to it.
202
But on the first load, it isn't going to wait for those asynchronous fetches to complete in order to render this component.
203
And so you can see there, there's a small, on the first load there, it said loading weather, dot, dot, dot.
204
And then on the second load, it was already there.
205
So that meant that that was going to come from the server as fast as possible because these child components, children components, weren't going to wait on their own asynchronous fetches,
206
but we could just load the shell and then stream those in when they're ready.
207
And then as soon as they're ready, they're cached for the next person and for the next visit to see, which is really, really cool.
208
And then if you wanted to go further with this, there's also this idea of cache navigations and also remote caching as well.
209
So if the in-memory cache isn't sort of long lived enough for you, you can reach out to an external service and start saving those cache entries in there as well.
210
So you get an even longer lived cache.
211
But yeah, I mean, that was the talk
212
that I gave at both of those meetups and it was just very cool to see where Next.js is now.
213
But like I said at the beginning, above all else, seeing just how much
214
that team care about making really performant apps and it's really quite inspiring to see and inspiring to show that, you know, we can all build things very quickly.
215
But if you care, you're going to build something really great and you can do that with Next.js, which is cool.
216
So I hope you enjoyed this.
217
If you have any questions, let me know.
218
I'll put a link to the demo app in the description as well, and you can grab that on GitHub, and I'll see you in the next one.

Vocabulary and speaking notes for this lesson

This C1 speaking lesson is built on the video “Next.js 16.3 got good”. This video has 218 sentences and 3420 words to shadow. The speech runs for 14:56. The speaker talks fast, about 229 words per minute, so expect linked and reduced sounds. 85% of the words are among the 3,000 most common in English; the rest is worth studying before you start.

Key vocabulary in this video

The 15 most advanced words in the video, with pronunciation and meaning:

WordPronunciationMeaning
cache noun/kæʃ/Such a store of physical supplies, placed by humans or other animals for practical reasons.
fetch verb/fɛt͡ʃ/To retrieve; to bear towards; to go and get.
render verb/ˈɹɛn.dɚ/To cause to become.
invalidate verb/ɪnˈvæl.əˌdeɪt/To make invalid (especially in to contract law)
declarative adjective/dɪˈklæɹ.ə.tɪv/Serving to declare; having the quality of a declaration.
egress noun/ˈiːɡɹɛs/An exit or way out.
asynchronous adjective/eɪˈsɪŋ.kɹə.nəs/Not synchronous; occurring at different times.
query noun/ˈkwɪɹ.i/A question, an inquiry (US), an enquiry (UK).
demo noun/ˈdɛm.oʊ/A demonstration or visual explanation.
optimize verb/ˈɑptɪmaɪz/To act optimistically or as an optimist.
revalidate verbTo validate again.
revalidation nounThe act of revalidating
spinner noun/ˈspɪnɚ/Someone who or something that spins.
parameter noun/pəˈɹæm.ə.tɚ/A value kept constant during an experiment, equation, calculation, or similar, but varied over other versions of the experiment, equation, calculation, etc.
refresh verb/ɹɪˈfɹɛʃ/To renew or revitalize.

Phrasal verbs you will hear

WordMeaning
add up verbTo take the sum of; to total.
go back to verbTo stem from; to originate in.
hold up verbTo wait or delay.
show off verbTo exhibit the best attributes of something.
check out verbTo record the departure or withdrawal of someone or something (such as guests, employees, books, etc.).
end up verbTo bring to a conclusion.
go down verbTo descend; to move from a higher place to a lower one.
go through verbTo travel from one end of something to the other.

Sentences worth repeating

Short, complete lines from the video that you can reuse in everyday conversation:

  • The agent's not going to care for you.
  • You're going to fetch too much data too often.
  • I don't need to do that.
  • I think I've stolen the next slide.

Grammar in this video

The structures the speaker uses most, with the exact words from the video:

StructureIn the video
Present perfect have/has + past participle — a past action that still matters nowI've titled · you've never been · has always been
Passive voice be + past participle — the focus is on what happens, not who does itwas cached · being fetched · are implemented
Relative clauses who / which + clause — extra information about a person or thingeverything, which is · fast, which is · people who build

Pronunciation to watch

The speaker uses 86 contractions and reduced forms, such as I'm, I've, don't. Say them the short way, as you hear them.

  • The “sh” and “zh” sounds: cache /kæʃ/, refresh /ɹɪˈfɹɛʃ/, differentiator /dɪf.əˈɹɛn.ʃi.eɪ.tə/, invocation /ˌɪn.voʊˈkeɪ.ʃən/, optimization /ˌɑptəmaɪˈzeɪʃən/
  • Long words — get the stress right: invalidate /ɪnˈvæl.əˌdeɪt/, declarative /dɪˈklæɹ.ə.tɪv/, asynchronous /eɪˈsɪŋ.kɹə.nəs/, parameter /pəˈɹæm.ə.tɚ/, ideally /aɪˈdi.ə.li/

How to practise with this video

  1. Listen to the whole video once without speaking and note the words you do not know.
  2. Start at 0.75× speed, shadow it sentence by sentence, then go back to normal speed once it feels easy.
  3. Record yourself and compare with the original, paying attention to words like cache, fetch, render.

What is the Shadowing Technique?

Shadowing is a science-backed language learning technique originally developed for professional interpreter training and popularized by polyglot Dr. Alexander Arguelles. The method is simple but powerful: you listen to native English audio and immediately repeat it out loud — like a shadow following the speaker with just a 1–2 second delay. Unlike passive listening or grammar drills, shadowing forces your brain and mouth muscles to simultaneously process and reproduce real speech patterns. Research shows it significantly improves pronunciation accuracy, intonation, rhythm, connected speech, listening comprehension, and speaking fluency — making it one of the most effective methods for IELTS Speaking preparation and real-world English communication.

Shadowing technique: read the full step-by-step guide →