Loading video player...
React makes it easy to build UIs, but
building fast React apps is a different
skill altogether. In this hands-on real
world React performance optimization
crash course, you'll learn how React
actually rerenders, why your app slows
down, and which performance patterns
truly matter in production. Not just
theory, but battle tested techniques
used by senior engineers. This video is
about knowing what to optimize, when to
optimize, and how to do it right. top
has created this course.
>> Hey, hello everyone. How are you doing?
Welcome back to performance patterns.
Yes, it's plural patterns because we are
going to talk about multiple patterns
that can help you to optimize
performance of your ReactJS app. What I
have seen in my career coding with
ReactJS extensively that most of the
performance concerns come from only one
thing that is rerendering. when your
react apps render when state changes
when props value changes when context
value changes if the parent component
rerenders isn't it so in all these cases
the rerendering may happen so if we can
control rerendering I think we'll be
able to address most of the performance
issues after understanding a part of
rerendering in react we are going to
talk about the techniques that we're
going to learn in this session is called
memorization derive state debounce and
throttle ling. We're also going to look
into splitting components,
virtualization, context optimization,
React compiler. These all are different
techniques through which you can control
performance degradation of your
application and each of these pointers
will bring design patterns that you can
adhere to to make sure that the
performance of your application is taken
care. As you can see, there are a lot of
things to be done. I thought of
splitting this session into two part one
and part two. As part of part one, we
are going to cover from moiation to
debounce and throttling and rest of the
pieces will be taken into the part two.
So before we start talking about any
techniques, it makes lot of sense to
look into rerendering and take some
examples. Here on your screen you are
seeing an application. This application
is a combination of a parent component
and a child component. This particular
text box what you see over here is part
of the parent component and on top of
that you're seeing something called
rendered colon two times that is a child
component. Now any changes that I make
in the parent component in state changes
of course the parent component will
rerender that's how react works. We have
spoken about it already when the state
changes props changes context value
changes or the parent component changes
the rerendering happen. So it's out of
React's own philosophy. If I change the
state of the parent component, the child
component also rerenders. This is how it
happens. If I put a letter over here, a
character over here like A, I am seeing
this two jump to four. If I type one
more V, it becomes six. If I keep
typing, it keep increasing. So it means
for every change of the state of the
parent component, the child component is
randing. Now you might be asking
question that okay fine it is
rerendering but why the value is going
double? Why it is not single? It is
because react runs something called a
strict mode. That's why the rerendering
happens twice. Okay this has happened
only on de mode if the strict mode is
on. If the same code is running on the
production mode this is not going to
happen. Now this is the parent component
which is called render tracker demo. So
what is this component doing? As I told
it has an input box. This is the input
box and it has a state called value.
What is happening? Whenever there is a
change happening in the input box, I'm
typing certain character. I am just
changing this value using the set value
updator function that I get from the use
state. We all know that that means I'm
changing the state of this particular
component. Now this component also has a
child component which is called render
tracker. We'll go there in a moment. Now
whenever a state value changes of this
parent component, React forces the child
component to rerender. That is why we
were seeing the rendering count. You
don't see the rendering count anywhere
in the parent component because the
rendering count is kept in the child
component. Let's go to the child
component. Now over here you are seeing
this rendering count. It is happening
renderscurren what I am showing this
simple react component act as an child
component over here which keeps tracks
of how many time it gets rendered. Now
if you have seen the previous session I
clearly called out the difference
between use state and user ref. Use
state with every render the value will
be flushed out cleared reinitialized but
for use ref in every render the value
will be retained and also changes of the
use ref value doesn't force for a render
whereas the changes of the state value
force for a render right we have learned
all these different nitty-g now here I
have used the use rate because I wanted
to preserve the value of rendering
across multiple renders and this is the
same exact value what I'm increasing I
am displaying also. So it means that if
my parent component rerenders due to
this state change value over here it is
forcing the child component also to
rerender and I'm able to see this over
here. That's exactly we are seeing over
here. So this is just to show you just
to set the ground that what rerendering
means and sometimes rerendering this
child component because parent component
is rrendering might cause a lot of
trouble. So all the techniques that
we'll be talking about today in the part
one are going to take care this kind of
rerendering which may not be required
how can we stop them in a optimal way.
The first technique is memorization.
What does it mean memorization is
basically a computer programming
optimization technique. techique I would
say which to speed up your program by
storing the result of a function's
execution and then use the stored result
the cacheed result if the input to the
function doesn't change. So if we take a
function say f(x) where x is the input
and it produces a result say y and now
we can cache this particular result and
anytime someone call this function we
will always return this same result as
long as the input provided to the
function remains same. This particular
technique is called memorization
technique. So it's a caching technique
where you can cache the output value of
a function and always return the same
value as long as the input to the
function remains same. If the input to
the function changes for example from X
if it become P of course it may not
going to return Y again right it's
probably going to return Z in that case
memorization technique won't be
returning the old Y value rather it is
going to catch the Z value and going to
return the Z value again this is how the
memorization technique works now in
React there are three different ways we
can do memorization technique first
using a function called memo that's
provided by React Second, React provide
a hook called use call back. Using that
we can apply memorization technique on
our React components. And the last one
is called a hook called use memo. Using
that also we can achieve the
memorization on our React component and
the React application. However, each of
these techniques has got their own
benefit and the disadvantages. We are
going to talk about each of these
technique going to show some examples.
However, in the modern React, there is
something called React Compiler which
we're going to cover in the part two.
And I've already created a video on
React Compiler extensively when it got
released initially. But I'm going to
talk about React compiler in the context
of the latest version of React in the
part two where we'll be talking about
how some of this memorization technique
like memo, use call back, use memo you
should be looking at if you are building
a React application from the scratch
today versus a React application that is
already there as a legacy code with you.
But that's part two. Now in part one,
let's take a look into each of these
technique one by one. First memo, then
use call back and then the use memo.
Take a look into this application almost
similar to the one that we have seen
before that whenever this application
got rendered first time it locked
something called rendered profile card.
It means that I have a component called
profile card and it render profile card.
Now let me tell you profile card is a
child component over here which is
showing the profile information. Now in
the parent component like before I have
a text box over here and look at what
happens when I type a key over here. I'm
typing a. The moment I type a the
profile card got the log for rendering
profile card came here. However, this
rendered profile card is there only in
the child component. It is not there in
the parent component. So it means like
before as you have seen once the parent
component is rerendering it is forcing
the child component also to rerender.
Now I keep typing character. If you see
in my right side console is going to
keep logging. It's again logging twice.
I have given this explanation before and
in fact you can see in the debugging
tool the one coming because of the
strict mode is in much more muted color.
Now let us take a look into the code.
This is a parent component. Again like
before I have a input box. I have a
state called value and I am changing the
value of it on every key type. And there
is a child component called profile
card. Whatsoever this profile card is
never ever related to this value. I am
not passing this value as a props at
all. I am passing a hard-coded name
called tapus. That means this profile
card is not changing because it has a
dynamic prop value. It is changing
because its parents state value I am
changing here using the onchange. You
see over here that's the reason by react
philosophy the child component is
reding. Now if I go inside this child
component, it's a very simple component.
takes the prop and it just says that
render the profile card and showing that
particular hardcoded prop. Now if I
think that I have a child component and
that child component I should not render
at any cost until unless the input to
the component changes I can use the
technique of memorization and the first
technique as I told is using the higher
order function that react provides
called memo. So the first thing that
we'll be doing is to import the higher
order function called memo from react.
So I've imported memo from React and
then you have to encapsulate this entire
React component function inside this
memo function. You know what higher
order function is. If you have followed
my 40 days of JavaScript, I have
clarified all these concepts very
clearly. A function that takes another
function as an argument or can return a
function from itself is called a higher
order function. So memo is a high order
function because now you can do
something like this. You can use this
memo and then you can pass this entire
component function that we had to get a
completely new memoized function. Now
this memoized function is your memorized
component. So instead of exporting the
profile card which you are doing before,
let us just export the memoise card.
Simple enough. So this is what you need
to do. That much alone is enough. So you
have imported the memo higher order
function. As it is a higher order
function, it can take another function
as an argument. You have passed your
component function got a memorized
function and you exporting from here.
Coming to your parent component there is
no changes required. If you just want
you can probably this name as a memoized
card because you are doing an export
default. You can import with any name.
It makes sense to do it as memoized card
because you can then recognize it's
something that you have memorized
intentionally. Now the behavior will
change here. First time when it got
rendered render profile card. Great. Now
I'm going to press one character. that's
going to change the state value of my
parent component. But this is never ever
going to change anything for my child
component because child component is
taking a hard-coded props. Right? So
first value if I'm pressing nothing
happens. My child component is not
rerendering because I am not getting
reader profile card again. I'll type
more characters. I'm keep typing
characters. You see here my child
component is not rendering. It is
because the memorization is done over
here and the child component is taking a
hard-coded value over here like so until
and unless this value gets changed this
props gets changed the child component
is never ever going to rerender even
when the parents component state value
is changing over here. So this is the
first step. Now let us understand the
next tool that we have is called use
call back for this memorization pattern.
Now I didn't show you the application
rather let us start with the code
because just now we have learned about
this memo isn't it the memoization. So
see this code should be familiar to you.
I have a component called child and this
child component is a very simple
component which takes a props and then
console.log says the child rendered and
return a simple button. The button has a
on click and click on it what function
to call that is what get passed as a
prop. So this is a very very simple
react component but the twist over here
is that this particular react component
is passed to the higher order function
called memo so that we get a memoized
version of it and this is what we have
exported from here. Cool very simple
memoized thing. Now let's go to the
parent component. We have imported the
child just like before parent component
has it own state called count. It got
its own button called increment. The
moment I click on this button, the value
of the count goes up by one using the
set count updator function. So on click,
I am calling this set count + one. It
means this count value will be increased
by one. It means I'm changing the state
of my parent component. I have also used
the child component over here. And as I
have explained, the child component
takes a onclick props which is over
here. I pass the function that should be
executed when somebody click on a button
which is inside the child component. Now
what do you think is going to happen if
the parents component state count gets
changed? So far we have learned that
using memoization if the child component
can be passed through the memo higher
order function until unless the input
gets changed my child component is never
going to rendered even if the parents
component state gets changed. parent
components render because of any reason.
So in this case, ARNU is satisfying two
cases. One, the child component is
already memorized and the props of the
child component, the props value of the
child component is quite static. It is
never going to change. So it means that
if the parent component state changes
because of this button click, the child
component should never get rerender. I
should not see this console.log lock
child render when I am clicking on this
increment button. This is what my
expectation. Now let's go and look into
the application. So first time of course
app render child rendered. That's great
because first time it has to render. Now
I'm going to click on this increment.
Look at here what happens. I click on
increment. Oh my god it again printed
app render child render and I click over
here app render child render. Oh my god.
So that means when parents component
state is getting changed, child
component is also getting rerendered
even when I have used the memoization
technique. Why is it so? So here basic
JavaScript come into picture guys. No
react nothing. React memo is fantastic.
It rerender your component only when the
prop changes. However, when comes inline
functions like this though it looks like
it's a static function I am passing to
on click. Now the beautiful part of
function is just like an object in
JavaScript it's of reference type. So on
every render a new reference of this
function will be created. So if a new
reference of this function gets created
on every render it means the onclick
value on every render of this component
is new. Isn't it? First time when my
parent component got rendered this
particular function's reference value
was let's say x. Now when I click on
this button to change the count value
that is the state of my parent component
my parent component will get rerender.
The moment the parent component get
rerender this particular line this
particular value will get a completely
new function which is having a new
reference in the memory. Though it may
look exactly same with the previous
version of it as it's a new reference
completely new function it means the
prop value had got changed. So of course
the child is going to get rerendered
even when the memoation has been
applied. So this is what you need to
really observe closely. Inline arrow
functions break memorization because
they create new identity every render.
This is the thumb rule. This is the
mental model that you need to keep it.
Now to fix this React gives us something
called use call back. That's a inbuilt
hook that react gives us which helps by
stabilizing the function references. So
it means that when I use use call back
hook use call back hook is never ever
going to look into only the shape of
this particular function rather it is
going to look into the reference of it.
So, so far whatever happened is like
inline function every render new
reference created. New reference got
created means browse value changed my
memo breaks and my child component got
rerendered. But with use callback it
will ensure that react dome will see
always the same object. Can you change
the code? Yes. Now to change the code
it's pretty simple. Let us take this one
the onclick one into a function called
handle click.
And over here let us import use call
back and define con handleclick equals
to use call back which takes a call back
function inside which you have to write
what you want to do. Let's say I write
console dot log of say clicked and then
you have to pass something called an
dependency array. So this dependency
array is similar to what we have seen in
use effect earlier right if you don't
pass anything it is just once but if you
can pass any dependencies whenever the
dependency changes only then you
explicitly tell that even if the
memorization applied on the child I want
to rerender the child but until unless
my dependencies are not changing their
value is not changing use callback would
ensure that even if you have a
memorization over here will ensure that
your child component doesn't get
rerendered right so that's the
difference so with this can we run this
app first time app render parent
rendered child render now let me click
on increment only app rendered I don't
see child rendered anymore only app
rendered only parent render rendered now
if I click on a button that is there in
the child I'll only see the child
rendered so click child clicked child
clicked only child rendered if I click
on the parent one only parent rendered
you see this now My memorization
technique is working really well. So
what are the things happened over here?
When I click on increment, my parent
component renders but the handleclick
function over here doesn't get recreated
because handle click is now very much
memorized using use call back. Child
receives the same function. This
handleclick function always on every
rerendering of the parent. As the handle
click is not been recreated, it always
pass the same reference. That means the
value of on click remain intact just
like before and then child doesn't get
rerendered. Now imagine if there is a
dependency value that I'm passing to use
call back and if the dependency value
changes only then this handle click will
have a new reference and that reference
value goes over here that means the
props value of child changes now child
gets red. This is exactly guys use
callback does. Now many people just use
the syntax but they may not understand
the depth of it like how it works. I
tried my best to give that to you. I
hope it makes sense to you and I want to
know like how is this 15 days of react
design pattern going guys if you are
taking this course I'm putting a lot of
effort believe me lot lot of effort I
would love if you can share a few words
about it in the public if you can tell
people like something like this exist so
that more developer who really wants to
learn and want to grow senior not you
know in terms of years and the age but
by experience of handling react project
for them this will be immensely useful
and making something out for free. I
feel really proud to giving back to the
dev community and if dev community also
can help me to spread the word about it
that will be really great thing. Thank
you guys. So let's move on to the next
one which is use memo. All right coming
back to the use memo. So here is a
simple demo. Okay, don't look into this
name too much. I have used the same
name. You can use many random names you
know for your demo. So what is happening
basically again the parent child
relationship and the components and all.
So the parent component is having this
number and the increment just like
before a count. So if I click on this
this number gets incremented that's it.
And the child component has a sorted
array and listed each of the name from
the sorted array. Right now I have
listed about thousand you can make it
like 10,000 100,000 1 million whatever
it is consider it's a big big big array.
Inside that array you are performing
sorting mechanism or sorting algorithm.
Now what happened due to our parent
child relationship and how react works.
We know that if the state value which is
the zero of the parent component changes
it is going to force this child
component also gets redender over here.
If you see on the first render user
component redender it is coming from
this particular sorting thing. This is
the user component. Now if I click on
the increment once more I can see the
user component red happened once more.
If I click again, if I click again, if I
click again, every time I click, it is
going to happen. Coming back to the
code, this is my parent component where
I have that button increment button. And
as you have guessed, there is a count
state. Clicking on that increment
button, I am setting the count by
incrementing it value by one. That's it.
That's what I'm that's all I'm doing.
Now, I also have this child component
where I'm listing all that usernames.
And the usernames are coming from a
method called say get user that I have
written in my utilities there. It can
return 10,000 100,000 usernames. Okay.
And this users is what I'm passing as a
prop to my users component which is a
child component. If I go to the users
component, it takes this prop. It put
this console.log. That's what we have
seen. User component rendered whenever
the count gets incremented. But here I
am doing an operation. I'm sorting it.
and then the sorted user I am putting
over here simple simple component but
there are lot of problem in the line
number four the first problem is I'm
sorting this array
which is a huge list of user object for
example now if it has say 100,000 user
object this is going to make this sort
every time this component gets
rerendered so that's the first problem
second problem I am actually mutating
the original list of user right which
may create certain issue because ideally
I should be creating a copy of it and
then only do the sorting as I am sorting
the large data and this is just getting
rerender on every button click or say
every key down it takes a lot of time to
process the sorting right so that slow
down my UI and we all know if the parent
renders child renders so sorting happens
every time now this is not a great use
of my energy and time to have this kind
of sort going Though we have taken the
example with sorting but there are other
such functions like filtering running
any kind of expensive computation
formatting heavy data doing object or
array transformation that produce new
functions new objects new references all
are going to create similar kind of
problem and that's exactly where use
memo comes in. Use memo helps you to
cache the computed value until its
dependencies change. Use call back. We
have learned that what it caches the
references until the dependency changes.
We have seen it with function. Use memo
cache the value until its dependency
changes. Imagine use memo as something
which memoize the return value of the
function and it cach it. It always
return you the same value if the input
remains same. If the input changes, it
is going to return you the change value
and again cache that value so that from
next time it can again return you the
cache value if the input doesn't change.
Now the same code we can change with use
memo pretty well and pretty easily. For
that purpose, first thing first import
use memo from react. Let me comment out
this sorted thing and let me write the
logic for sorted using use memo. So I'll
have use memo. This again take a call
back function and just like use call
back you can pass a bunch of
dependencies over here instead of
mutating this list directly how I was
doing before let me first create a copy
of that list using the spread operator
and on top of that I can do this sorting
logic so I'll be just copy pasting this
one and this is going to return me new
sorted array that's I'm going to return
and as and when the list changes I am
ready to do this computation if the list
doesn't change I'm not ready to do this
computation so you understood use memo
is a hook that takes a function and a
dependency array that dependency array
decides when the input changes then only
whatever you have written inside this
callback function has to execute
otherwise it won't so what execution we
are doing if this list changes then only
it makes sense to sort it again and then
the return value will be over here which
we are already using to map it out
Great, isn't it? All right. Now, let's
go to the UI and see what's happening.
So, first time on the first render, it
says the user component rendered. Great.
Parent rendered and child also rendered
and it's sorting the expensive list. So,
first time the use memo got called
because list the value of list supplied
for the first time to the child
component, the user component. Now, if I
increment, what happened? If I am
incrementing, I'm saying that user
component rendered this log I got.
However, this sorting expensive list log
has not come. That means if I keep
incrementing, of course, my parent
component state value changing. So why
my child component is also getting
rerender? Because child component I have
not memoized. Enter component I have not
used in this case inside the memo higher
order function. So it will definitely
rerender. But even if it is rerendering
the heavy computational logic, the
sorting logic that is not getting
executed. See I'm incrementing
incrementing only first time it came
sorting expensive list but rest of the
time it is not coming. So if I go to the
code again this will be coming every
time because this child component is
getting rerendering that's fine I'm
completely fine with that but this
computation is not happening again
because this list is quite static that's
what I have got from my utility function
if this list changes only then it will
be recalculated again and only when you
will see this console.log log once
again. So for any kind of such expensive
operation, it's always good to use use
memo. Now again the catch over here is
please don't use use memo for any
smaller computations. It is not going to
save you much. See even to look into
like if some value is cached and then
only return the cache value or return
the new value, it requires certain
computation within React is computing
something at the background, right? Now
for a smaller calculation like like for
5,000 10,000 values why would you do
that? If the value really grows where
your application performance the search
the button click adding to the cart
something is getting very much sluggish
only in those cases think about using
it. Don't use it just because it is
there sometime eagerly optimize the
performance of your application may
introduce more performance bottleneck.
So you have to be really careful where
you should be using where you should not
be using. So I hope the memorization
technique is quite clear to you. Now let
us talk about the second technique. Can
you sense what is wrong here in this
code? So this is a simple cart
component. What I'm doing basically I'm
taking the number of items that are
there in the cart and then computing the
total number of price that somebody has
to pay the total amount somebody has to
pay to purchase the item there in the
cart. And then I'm just rendering that
total value over here. Very simple. I
kept this use effect over here to
calculate the total sum the total amount
that somebody has to pay and that's how
after computing the amount I'm just
changing my state variable and this is
what is going to reflect over here is
there a problem that you see in this
code if I run this code it will
beautifully run if I just pass an array
of items with their price it is
definitely going to run and give me the
total rendered on the component then
what is the problem the problem here is
with something called derived state
that's another thing that cause a lot of
performance problem if we are not
careful. What is a derived state?
Derived state is any value that can be
computed from existing state or props.
Okay, again I'll repeat a derived state
is any value that can be computed from
existing state or props. For example,
you have a list, you can derive the
filtered list from there. You have the
cart items, you can derive the total
amount for the cart. You have a text,
you can derive the length of the text.
you have a boolean you can derive the
enable disabled states from that derive
state should not be stored in another
react state. This is a problem I have
seen tons of time whenever I reviewed
code in my life. Derived state again the
rule derived state should not be stored
in react state. Why? Because storing it
cause unnecessary renders which is the
cause of many problems in terms of
performance of your react application.
Secondly, if you are storing derived
state as another react state, you have
to synchronize between the original
state versus the derived state. What if
your original state becomes still your
derived state still out of sync? You
have to do lot of complex logic sometime
to manage the synchronization, right?
And always you're doubling down on the
rerendering whenever certain updates
happening. Why do you want to do that?
So that's exactly the problem over here.
Now if the same cart component I have to
rewrite as a better cart, it will be
much more simpler. See how it is. I'm
getting the items from items using the
JavaScript reduce method which is the
exactly same logic that I have used over
here. I am now computing the total and
then rendering the total. That's it.
Whenever the props change this value
will change. Why? I have to do another
use effect. I have to manage another
state another derived value for this as
a state and use it. Now there is no
basically unnecessary things happening
over here. Right? I have reduced the
load a lot. I have written very very
less number of code over here. So this
is an antiattern storing derived state
in use state what we have seen over
here. Please stay away from this. Now
here is one more example. Tell me
whether it's a good example or bad
example. I have the users component. I
am taking a list of users and then I am
filtering this. Maybe this list contains
100,000 users. So of course I have used
use memo. By now you know why we used
memo. is a expensive time-taking
computation. So as long as the user list
stays same, I don't want to filter them
again and again. So it filters filter
out only the active users using this
user.active. This active users get
returned and I'm using active users over
here as a map. Is it a good practice bad
practice? Now first thing you need to
answer am I using any derived state? No,
because I have not declared anything
with use state and this particular guy
whatever I'm using in my JSX is not a
state because to make it as a state
either I have to use use state use reduc
or things like that I'm not using it's a
simple variable that returns a heavily
computed value. I'm using use memo
because I care for it because my list
may have 100,000 1 million users. So
active users now has computed heavily
computed user value and then filtered
user value. Active user value and then
I'm just rendering on my JSX. That's it.
Simple. So no derived state. It's a good
way of doing things. However, this one
of course this is wrong because I get an
age. Then again like before based on the
age value I am checking whether the age
is greater than equals to 18 or not. In
that case the person is adult. So I have
a boolean value is adult and based on
that I'm saying adult or minor. I don't
need this computation inside use effect.
I don't need this derived state. I get
the age. I just have a variable called
const is adult equals to age greater
than equals to 18 and then use is adult
directly over here in this condition.
That's it. Correct? So no derive state
no drama extra drama in your code. This
is another one I have seen in terms of
form. This is taking name and email. I
have to validate it. Why would I create
again a state called is valid? And again
why I use is effect unnecessarily.
Whenever the name and email changes I am
marking as whether the is valid is true
or false and based on that I'm taking a
call. No don't do that rather create a
variable called const is valid equals to
this particular logic. So whenever name
and email prop changes that will be
called and then is valid you use as it
is. That's it. No derived state at all.
So these are some of the practices I
hope that you keep in mind and I hope
you understand why derived state is bad
and how you can get rid of it as much as
possible. Now let's go to the next
technique. The next performance
technique or the pattern that we're
going to talk about is called the
bouncing. Now again if you are someone
who is following me and following 40
days of JavaScript you know that I had a
session on performance optimization of
your JavaScript app and there I have
explained debouncing and throttling and
concept like that visually right now I'm
going to explain it over here also but
let's see the problem first. Let's
imagine this is a portal where I can
search user and this makes an
asynchronous call on an API fetch the
data over the network and display the
search result the match result at the
bottom. I have not implemented that ent
but I've implemented it so far so that I
can show you the demo. So here as and
when I type something like tapas if I
type on my every keystroke you can see a
console.lo block appearing over here
which is given at the place where I'm
making the API call. So if I type T A P
A S if you see that I have made a API
call with T A T A T A T A P A S it means
that for every key stroke I have made an
API call now this API calls are not
cheaper they are costly they are
expensive why they are expensive because
you have to make them over the network
and then some of the API calls may have
rate limit you probably have to pay for
those API calls once you pass the
threshold so you got to be very sure
that you are not going to call this API
so rapidly rather you need to have
certain mechanism where you can actually
control this. This is where debouncing
come into picture. So what debouncsing
is debouncing is a technique through
which you can delay the execution of a
function by certain time. Okay. Now one
thing you have to remember over here
whenever I'm typing something on my
input text box I am actually generating
triggering an event that is what
onchange event now through debouncing
you are not controlling that event you
cannot control that event the event will
happen the onchange event will trigger
but due to the onchange event triggering
you were calling certain function of the
API you can control that okay some folks
they get confused with oh debouncing
means I don't trigger the event at all.
No, event will be triggered. But due to
that event trigger, there used to be a
function call. That function call will
not happen for a specified time that you
decide what is the specified time. All
right. So this is what the debouncing as
a whole. Now to implement this
debouncing in React, we'll be creating a
hook and I'm going to explain the code
in detail. But before that, so far look
into this search component. The search
box component. As usual, it has a state
called query. Query means whatever you
are typing inside the search box
whatever the value that you type inside
the search box that value set inside
this query variable and you update the
value every time somebody type on this
input type text box using something
called onchange right this is change
event and using the set query updator
function whatever the value there inside
the input box you set as a query and
your state value gets updated you have a
use effect we all know what it is it has
a dependency called the same query so it
means that whenever the query gets
updated let's make an API call and here
we have simulated an API call like fetch
call I don't have the call in in real
just assuming there is an API so what is
happening every time I'm key in I'm
changing something this query gets
changed and this use effect gets
executed I'm seeing this API call with
this query every keystroke now my
intention would be I limit that I don't
make this call I don't make this one
executed for a specified time delay For
that purpose I have now a hook called
use debounce. This takes two parameter
very important. One is a value which
basically influence the change of the
query. Basically that's the value and
there is a delay that I specify. Here I
have put a default delay of 500
millisecond. You can put the delay
whatever the delay that you want. Now if
a delay is passed from outside this will
be overridden. This 500 millisecond will
be overridden. If it is not passed from
outside it will take the 500 millcond.
The best part over here is this guy.
This is the heart of debouncing. It's
called set timeout. What does set
timeout do? Set timeout deferred calling
a function for a specified duration that
you provide. So here set timeout will
defer running this function for this
amount of delay that you have given. Now
what is this function doing? This
function is setting something called
debounce value. That's exactly with the
value that I have passed to this use
debounce. And this set debounce value
seems to be a state. So it means that if
I do set debounce value over here, it is
nothing but setting this particular
value which I'm ultimately returning
from here. Okay. So it means that even
if the value comes over here, the return
value from here is happening only after
the delay that I am specifying. Okay. So
I am actually giving you an updated
value back only after a particular
delay. That's all this use debounce is
doing. Once this delay expires
then I am again giving you the updated
value. Until the delay expires I am not
giving you the updated value because
until this delay happening this
particular function is never going to
get called. If this function is never
going to get called this debounce value
won't be set with a new value and you
won't get a new value as simple as that.
Also please notice in this user fact I
have a cleanup method called clear
timeout. Whenever you are using
something called set time out or set
interval, you have to ensure that you
clearing them as well. Okay. Now, use
debounce is what I got. Now, how can I
use it in my search box? Let's see that.
So, first thing first, let's import use
debounce. I have imported use debounce.
Call is debounce over here. Pass the
query and I'm passing a new delay. Now,
if it takes this query, this query is
again what? Whatever I'm putting inside
the input box. So every time I put
something like I put t I put ta I put t
a p every time I do that it goes to use
debounce as a value and there is a delay
given till the delay is there it is not
going to get set with any of the value
that you're passing here not with t not
with ta not with tap as it is not
getting set with any new value the value
that you get from here is always the old
value now once this is get expired that
point in time whatever the value you
passed with that value this debounce
value will be reset and it is returned.
Okay. So that value come over here and
now everywhere that we used query
instead of that let's use debounce
query. See so that's all the code is
right. So now instead of query I'm using
a debounced query which is a result that
was created out of the query itself but
after a delay whatever the accumulated
query I got I am returning only that and
so the output of this was also changed
before for each keystroke I used to get
that I'm making an API call now I won't
get that I'll get it only after 600
millisecond since I last type so if I
type a a a see I'm not getting anything
on the right side Now I'll get a 600
mcond pause. Yes, I got it again. E E E
E E E E E E E E E E E E E E E E E E E E
E E E E E E E E E E E E E E E E E E E E
E E E E E E Now 600 see now difference
first it has taken where I stopped all
the A's. Then again where I stopped A E
E that's what you have right so instead
of making an API call how many A are
there probably eight A's and four E
instead of making 12 calls over here I'm
making just one call that's a huge
performance bone if I keep typing things
also see I'll make just one API call
over here but before without that I used
to make API call for each of the
characters that's a huge performance
boon don't you think so this is what
debounce does for us guys so that's
another technique the last one is about
throttling last one means since part
one's last one. Okay, part two have lot
more to cover. So in the part one, we're
going to talk about throttling. First,
let's see the demo. So I have a bunch of
items on this UI and again look into the
right side console.log. What I'm going
to do now, I'm start scrolling this one
and this is going to show the scroll
position. That's not very important. But
in the right side, if you see how often
I'm making some DOM manipulation. Okay,
I'm scrolling very slowly. You see, I'm
scrolling very slowly. showing actually
the scroll position over here four five
but this one almost 28 times it got
rerendered almost 28 times I made a do
manipulation now see it is going to
increased and very slowly very slowly
I'm scrolling it's increasing as the
scroll y position is increasing as the
scroll y position is increasing I'm
seeing this guy also getting increasing
now imagine if you are doing certain
painting you're doing certain dom
manipulation calculation and every
scroll movement if you are doing it
minute movement of your scroll position
and if the DOM computation manipulation
is something which is bit heavier this
is not a good thing to do that's why
throttling come into picture so what is
throttling debouncing where we can defer
a particular function execution or the
value generation for a certain period of
time we can delay it the throttling is
little bit different in throttling we
say that within a specified span of time
I want certain things to happen at most
once once the span is over time span is
over again I can make it happen that's a
very big difference between uh
debouncing and throttling however many
gets confused let me just reiterate
again for everyone's sake debouncing is
delaying an execution of a function or
getting a value out of something for a
specified duration so for that duration
a particular execution particular
operation is not going to repeat or take
place however for throttling for a
particular duration a operation is going
to take place but it is going to take
place at most once that's the difference
now here also we'll be using another
hook called use throttle and the logic
is pretty simple over here as well what
I do we get that value that we want to
throttle throttle means this particular
value is going to change at most once
within this particular time frame if I
pass a bigger time frame from outside of
course it will take that what I want to
track over here when this value was last
changed. Okay. So we track it with last
executed something called which is
called dead dot now when it got last
changed and here we are computing that
right now whatever the time is which is
right now and when it was last change
the difference between these two whether
it is greater than equals to the delay
that I have specified. Imagine if the
last change happened on say 10:00 and
the next change is happening at 10:15
that means there is a gap of 15 minutes
in this computation. Now if I have given
a delay of 20 minutes this 15 minutes
has not crossed the 20 minutes delay. So
the function call is not going to
happen. The new value generation is not
going to happen. If this delay is say 10
minutes but this difference is coming 15
minutes that means I have already
crossed my 10 minutes delay. So I'm
allowing the recomputation of this value
or the function call again. That's all
guys about throttling. This is the core
logic of throttling. Nothing more than
that. So it means that if a value get
passed, I'm actually throttling that
value for this duration. Once the
duration is passed, I'm allowing it to
set a new value and the new value the
throttle value is what returning from
here. This is what the use throttle hook
is. Very very simple JavaScript logic
basically. Now to make it work pretty
simple. I have to first import
use throttle over here and then instead
of having this scroll y value which I'm
showing over here right let's do one
thing let's use the use throttle pass
the scroll y over here and pass this a
big time a large time maybe 3 seconds
right and this throttle y value instead
of scroll y we'll be using over here now
let us go to the UI refresh this refresh
this
now I'm going to scroll down slowly
again see I'll start scrolling I'm
scrolling okay I got after 3 seconds see
it is not coming on my every scroll look
at the time I'm scrolling look at the
scroll and the things coming at the
right side is much much reduced right
now correct so for every scroll it is
not coming it is coming only after every
3 seconds it is happening only once so
my DOM manipulation has reduced a lot so
as promised we have covered memorization
derive state debounce and throttle we
also spoke about rerendering and the
problem due to that in the next session
the part two we are going to cover the
splitting components methodology
virtualization going to talk about the
context optimization and also about the
react compiler however you know that
none of our session gets over without a
task right this session even know even
though it's a part one has it task let's
take a look into that okay so these are
the task of your part one fix the broken
memorization take a look into this
particular code and the task is to make
sure the child renders only once Even
after repeatedly clicking on increment,
I have showed this already, right? So
you can fix it easily. Then improve the
derived state antiattern. I have a
filter thing and I am just doing this
state changes based on something. So you
know that I'm not giving you hint. And
then build a small dashboard basically a
search bar with debounce a scroll
tracker with throttle. I have showed it
and then the user list with a 10k or
more filtered by search no derived state
with performance optimization. all the
techniques that I have showed using that
just do this very simple once you do
this task I'm sure that this learning is
going to go inside your brain and you
are never going to forget it all the
code will be inside day 11 folder come
to performance patterns come to the src
performance folder and then you have
memorization debouncing rerendering you
know derived state throttling all this
whatever examples I've covered
everything over here you know how to
grab it you have to go to
github.com/tubberscript
Please follow this because I keep
sharing a lot of awesome repositories
over here and then you can go to 15 days
of React design patterns.
Once this video is published, you will
see day 11 and all this code that I've
showed over here will be there. Also
join Tapascript Discord where you can
talk to other developers and we also can
talk sometime and discuss things. Okay
guys, stay tuned for part two and show
your love. Please subscribe to
Tapascript. Spread the words about the
thing that I'm doing. That will be great
help. Thank you. Take care. Hey. Hello
everyone. Welcome back to the part two
of React performance mastery. If you
like the part one where we spoke a lot
about rerendering, memorizations and all
things around it, part two is going to
be a lot advanced. Though is advanced
but you don't have to really worry if
you are just a beginner to react. We are
going to go through each of the use
cases, problem with lot of examples and
easy to understand language so that you
get the entire cracks of it and you'll
be able to utilize and use all these
things that we'll be discussing in this
video in your day-to-day application.
Excited? Yes, I am also very excited. If
you're coming to part two directly, one
request would be first finish the part
one and then finish the task and then
come to part two. You know if you want
to learn something deep, if you want to
learn something well, there is no
shortcut to it. Take some time, give
yourself some time and that's how you
learn things better and you learn thing
one for all. Let's check out what's
there in part two. We have already
learned about memorization, derive
state, debounce, throttling etc. In part
two, we are going to learn about how
splitting components logically can save
a lot of time and can boost the
performance. What is virtualization
mean? where to use it, what are the
benefit and how we can do and how we can
gain on performance because of using
this technique. We're going to talk
about context optimization. What is
context? We know about react context but
how can we optimize it. So there are
certain rules and technique. We're going
to talk about them. We're going to talk
about React compiler. And apart from
these four things, I'm also going to
talk about a few great practices that
you can adopt while programming in React
so that the performance concern is taken
care from the first line of the code
that you'll be writing for your project.
And as usual at the end I will give you
certain task and assignments that I
always encourage you to do because once
you do those task and assignments after
taking the session your learning is
going to be solidified and you are not
going to forget the things that you're
learning out of this you are spending
some time right out of your life let it
be of a great use. React 19 introduced
something called React compiler which
automatically memorize components,
stabilizes the function references and
prevents unnecessary rendering without
requiring any manual effort from
developer in writing use memo or use
callback. In part one, we have learned
about react.mmo, use memo, use callback.
All these utilities only purpose of
those utilities were that they save you
from unnecessary rdering. Until unless a
dependency changes for a component, your
component is never going to rerender,
never going to execute a function
multiple times, never going to
recalculate certain values. But for all
those things, we had to provide
react.mmo, use memo, use callback, all
these things with our hand by code,
right? But now what we are saying as
react 19 got react compiler in it we
really don't have to write react dome
use memo use call back all these things
this is huge don't you think it will
reduce a lot of code lot of boiler plate
and a dozens of accidental performance
issue in the part one I emphasized about
one fact use memo used callback are
great things but sometime we overuse
them we kill the code and now what react
is promising if you use React Compiler,
you don't have to use those things by
yourself. That's great. Now, if we draw
a comparison before React 19 and after
React compiler came into picture before
React 19 developer had to manually
optimize things using use memo, use
callback, React dome, right? You
remember we spoke about it that inline
objects and the functions can break
memorization. That's the reason we were
using use call back and all this stuff.
And the other problem was with every
render the values were getting
recreated. So if that value was created
out of a heavy computation it was too
much to take care for a component. Now
after react compiler came into picture
the best thing that happened component
outputs get memorized automatically
behind the scene. Functions get
stabilized automatically behind the
scenes. You as a developer write less
code and React optimizes more. So what
does it mean to you? I'm sure you
recognize this code isn't it? I'm using
the use memo hook and consider just
assume that there is a heavy operation
happening over here until unless the
value of amount changes. I don't want
this amount multiplied by two to be
recalculated. So I'm caching the result
as long as the input to this is
remaining same. I'm not going to
recomputee it. I was doing it because I
assume that multiplying by two of this
particular amount is a heavy operation
just for the example sake. So I don't
want to recomputee this again and again
as long as the value of the amount
remains same. Now this is the old way.
Let's write it. This is old way. Now
what will be the new way? If you use
react compiler, how will you refactor
this code? That's all. That's all you're
going to do. There is no use memo at
all. You have the amount you multiply by
two and you assign to a total variable
as you were doing before. You remember
as you notice I'm not using use memo.
I'm not defining what is the dependency
of the use memo. I'm not telling React
anymore when to cache, when to
recalculate a thing. React will take
care of the things at the background for
me. I don't have to really do anything
for this. Configuring React compiler on
your React 19 or 19 plus React codebase
is pretty straightforward. The only
thing you need it to install this dev
dependency. You have to install Babel
plug-in React compiler. That's all.
That's the only thing you need. As I'm
using yarn, I'm using I'm installing it
using yarn at command. Minus capital D
stands for the dev dependencies. If I
install this after a successful
installation, I will find it over here
in my package.json file. And then I have
to do one simple configuration in my
configuration file. That configuration
depends on what kind of project
environment you are running. I am
running this React application in a
Vbased environment. You can see
v.config.js
file over here. If you are running on
Vidbased environment, there is one kind
of configuration. If you're running it
on a Babel based environment, one kind
of configuration. If you're running on a
Nex or React router DOM, for everything,
there are different kind of
configurations. Each of the
configuration steps are very well
documented on React website, React
documentation, you can take a look. I
have also provided the direct link to
that in the description of this video.
Now, if I take a look into what kind of
configuration I need for Vbas project,
it's pretty simple. You remember you
just now installed Babel plug-in React
compiler. So the v.config.js
file has given a definition of that same
plug-in over here. Ideally, originally
you will find your vid.config.js file
like this. There won't be any argument
passed to this react. Now what I have
done is just passing this particular
argument that this is a babel plug-in
and the plug-in name is babel plug-in
react compiler. the same thing that what
we have installed. That's all you need
to enable React compiler on your React
19 or React 19 plus project. Now what
does it mean to us? We have done all
this thing. How do we know even that
this is working? For that, let me first
run the server locally. So it's running
on local host 5173. Let me go to
browser. Don't worry whatever is shown
over here for a moment. But if you open
up your dev tools, if you have installed
react dev tools extension for Chrome,
Firefox, age, whatever browser, whatever
your favorite browser is, just install
that extension react developer tools. In
that there will be something called
components. If you come to components,
you will see that your entire hierarchy,
entire component hierarchy having a tag
called memo. You see that beside
everything is called memo. This means
that the React compiler is now activated
on your entire component tree and each
of your components are automemorized.
You have not done any use memo. You have
not done any use call back by yourself.
This is automemoized. Okay. So this is
how you can figure it out. Now you don't
have to use use memo. You don't have to
use react dome. You don't have to use
use callback. Your entire application is
memorized. But sometime what happens?
You might want to opt out from
memorizing your component automatically
by React compiler. On that case, you can
use this directive in your component.
Inside your component, you define a
component using function, right?
Functional component function. Then the
component name inside that you can use
this directive called use no memo. If
you use that, then this particular
component will temporarily be opted out
from the optimization of React compiler.
Now when you should be doing this if you
find that there is a problem with this
component using along with the react
compiler only in that case you will be
opting out but in most of the cases the
recommendation is if you're on react 19
and above don't use this one use and
activate for the entire project see if
you're facing any issue then use this
particular directive isolate this
component out of your React compiler
perspective fix the issue and then
remove the directive I hope that makes
sense. to you. Now having said that if
you want to understand or take a deep
dive of how React compiler works
internally in general if you are from
computer science and engineering
background you must have learned about
compiler. You must have understood
compiler in your academic years. Now how
the phases of compiler are related to
react compiler and how react compiler
take your component code what it does
what kind of translation happen
internally so that it can improve this
performance if you want to get deeper
into it I have created a video for you
already so please take a look into that
video also I have written a complete
guide and published on free code cam
some time back you can take a look into
that resource as well I have given a
link to both of them in the description
of this video so that you find it handy
and you can learn from it. So that's
about React compiler which can really
make your performance boosted for your
application provided you're on React 19
or above. Last thing, React compiler
best used with React 19, it can still
work with React 17 and 18. In case
you're still in React 17 and 18 and you
want to utilize React compiler with it,
here is something simple and realistic
for you. React compiler is not a magic.
While React compiler gives a lot of
things automatically help you writing
lesser code but you still need to
optimize a few things. You still need to
know how to optimize a large list in
your application. You still need to know
how to optimize context value. You still
need to know how to do component
splitting correctly. You need to know
how to do lazy loading. You need to take
care of something called virtualization.
You need to know about what suspense
means. You need to know about the
concurrency and the transitions. All
these thing come together along with the
optimization of React compiler to give
you the best thing about performance.
And believe me, there is nothing that
you have to do extra. There is nothing
that you have to do special. You just
need to follow certain good practices,
standard practices when you are thinking
about coding in React. When you have a
use case and you want to translate that
into your component before well before
you start writing your first line of
code for the component please take a
pause think about the use case that you
have in hand for example do you have a
long list of item to render all the data
came from the server to the browser and
you have to tackle this large list you
have to do certain lazy loading when you
have to do certain kind of transitions
all this thing is what you need to think
prior before you start writing your
component so in the next section I'm
going to introduce to you about code
splitting and lazy loading. Big
application means big bundles. Big
bundles means one application you have
you have written the code you have to
build that application so that you
create certain bundles certain artifacts
that you deploy on a server and then on
a public IP your customer can access
that deployed artifacts that's your
application. So when application gets
bigger the bundles get bigger and once
bundles get bigger wherever it is
deployed to from that place it has to be
downloaded on your client's browser. Now
depending on the network latency and
everything the download might really
take certain amount of time. So it means
your application may get slow startup.
Lazy loading allows you to load only
what is needed and when it is needed. It
improves time to interactive. That means
that when user click on something the
interaction point the perceived
usability of that element will be much
much faster reduced bundle size and as I
was saying because of these two
perceived performance increases. Now let
us take some example to understand how
lazy loading works with lazy loading
without lazy loading what is the
experience that our end user gets for an
application. All right, let's talk about
two components. One is called light.jsx,
another called heavy.jsx. What light
do.jsx is doing a very simple react
component, right? It has a simple
console.lo, you can ignore it. But what
it returns, it returns a div which is
having some kind of style and then it
has a h2, it has a paragraph, a
presentational component which we
sometime call as a dumb component also,
right? It's a component that's name is
light. It's a lightweight component.
Along with that, we have another
component called heavy component. Okay,
heavy weight component. What does it do?
Let's see. The heavy component does a
heavy computation. It generates some big
data. You know, maybe a array of this
many element. You know, as operation is
heavy, we are using use memo. Why we are
using use memo? If you're coming from
the part one, you know why we are using
it. So, we get the data. After getting
the data, we are rendering the data's
length and then certain textual
elements. That's what we are rendering
over here. So, this is what the heavy
component is doing. Now let's take a
look into a component called non- lazy
loader. So this is my demo about a
component hierarchy where lazy loading
is not used. I have imported both light
and heavy. In the non- lazy loader I'm
using this light. As you can see there
are of course few textual information
and then I have a button. Whenever I
click on this button I toggle a state
called show. Show hide. Show he hide
like this. So whenever show is true only
in that case I'm showing this heavy
component. So it means that if I now
render this non-lazyl loader jsx from my
app.t JSX file I will see this bunch of
text I will see a bunch of text coming
from light I will see a button if I
click on that button first time I will
see heavy if I click on it again I will
hide the heavy that's what this
particular component is doing but there
are lot of story happening in the
background let me first open up the
application on browser let us first see
what is happening yes non- lazy demo of
course a bunch of text this is coming
from the light component and here is a
toggle if I click on it it toggled And I
saw this one is getting rendered. If I
click on it, it will be hidden. Show
hide. Show hide. All grid. Now let's go
to the developer tool using F12. And
let's go to the network tab for a
moment. Let me reduce it little bit so
that I can capture everything. And now I
have this disable cache mode. That means
nothing is cached. And I want to
throttle this to say slow 4G. Okay. Now
what I'll be doing I'll be just
refreshing this one but before that I'll
select all as a filter. Okay so that
everything gets captured and let's
refresh this one. So you're seeing
things are coming it will be slower
because I'm running on slow 4G. Light is
taking some time. It took around 2.52
millisecond. Heavy took around 2.57
millisecond. And then after light and
heavy both got downloaded I am getting
this entire UI getting rendered. Heavy
is something where heavy computation is
happening. Okay, I'm using react memo
but react memo will be impacted only
from the second time. First time when it
is rendering the calculation has to
happen even if the use memo is there
right on the first render. So on the
first render I am blocking the rendering
of this entire component until I
downloaded light and heavy completely.
But have you noticed this heavy the
output of the heavy component the
rendering part of the heavy component I
need in my application only when
somebody click on this show heavy then
only I'm showing the rendering part of
the heavy component unless somebody
click on this show heavy I don't need
this heavy component on my UI at all
then why am I downloading the content so
much thing from this heavy.jsx JSX on
the browser. Why am I putting this
unnecessary load? Imagine somebody is in
a slow 4G network. That person is going
to see a wide screen. Still nothing is
there. See this heavy is spending light
is spending. Now once heavy came up,
still it is processing. Now it got it.
So this is completely unnecessary.
Right? This is why lazy loading can come
into picture. So as you can guess
correctly now with lazy loading I can
now lazily load this heavy component
because the rendering of this heavy
component is not required at the first
shot of rendering of this enter
component. The rendering of the heavy
component is required only when somebody
click on this show heavy then only I can
go selectively fetch the heavy component
load that heavy component and then
render that heavy component. that
reduces a lot of rendering time on the
first load and then improve the user
experience because I can now
additionally do like a loading state
when somebody first time click on this
show heavy while I'm downloading this
particular component lazily and then
attaching to my component hierarchy till
then I can show certain kind of loading
indicator I can fall back to a loading
indicator till the component is
completely ready for me that's where
I'll be using something called lazy
loading along with suspense. Now can we
see instead of non-lazy loader.jsx a
lazy loader.jsx. So in non lazy
loader.jsx we had imported light and
heavy directly. But now I know heavy is
something that is coming only when user
interact with the link. It doesn't need
to be there. It doesn't need to be
downloaded at the first shot. So I'm
using something called react.azy. This
comes from react itself. You can also do
import lazy from react or you can write
react. lazy directly. Now here you pass
a function. The return of the function
should be an import statement where you
pass what you want to lazily import the
path to that. So here I'm saying I have
a component file called heavy. Please
import that particular component
dynamically and as you're importing this
component dynamically I'm passing that
to react lazy so that it takes care of
it lazy loading and it gives me back
this component which I can now place
conditionally somewhere where I want
this particular component output to be
lazily rendered so far with me rest of
the pieces are exactly same just like
before I have a state called show and
hide for showing and hide just like
before I have this H1 I have this P just
like before I have this light But I have
now introduced something super exciting
something called suspense. What does it
do? Suspense come up with something
called a fallback. And it expect certain
thing to be rendered as synchronously.
It means whenever this guy show whenever
this show is true I am going to show
this heavy isn't it? That's my
condition. This heavy was not imported
like light not statically imported. It
is dynamically imported along with lazy.
Now to render that you need something
called a suspense along with a fallback
saying that till the point this content
of heavy gets downloaded and fully get
begged and rendered on your browser show
something in the meantime. So it means
when someone click on this button set
the state of show as true react will
start importing this heavy downloading
the content of it on the browser baking
it and rendering it. Till that point in
time suspense will show this particular
div saying that loading heavy component
and once this guy is ready to show ready
to render this fallback will go over and
we will see the content of heavy. What
are we achieving by doing this? Of
course the first thing first when this
component lazy loader component gets
rendered it doesn't render heavy. It it
just render H1 P and light. That means
I'm not downloading the heavy component.
I'm not downloading the content of the
heavy component. I'm not doing this
extra rendering. When someone click on
this button being reactive then only I
am downloading the heavy component. Then
only I'm importing the heavy component,
downloading the content of the heavy
component, rendering the heavy
component. Till that time I'm showing a
fallback as well. This is the change.
Can we see the output of this? So before
I show the output of that, let's take a
look into one more thing. when I'm
refreshing that just take a look that
both light and heavy is getting
downloaded well before I click on the
link in my previous non- lazy version
correct both light and heavy is now
downloaded now I'll go ahead instead of
non- lazy I'll import the lazy version
of it and I'll use the lazy loader part
of it okay now let me go back to the UI
I'll clean it up I'll refresh it now see
the magic see things over here okay
getting downloaded Light is getting
downloaded. After light only I see this
UI got downloaded. I don't see heavy
here at all. I used to see heavy here
along with light in my previous example
because light and heavy both were
statically imported. Both were getting
loaded when this particular component
was getting rendered. But now as heavy
is dynamically imported and dynamically
rendered based on this condition of
clicking on this show heavy until unless
I click on show heavy I don't find heavy
at all and that's the reason this
particular UI in this time even with
slow 4G disabled cache came up much much
faster because the heavy computation was
not getting done in the background. Now
what I'm going to do, I'm going to clear
this up just to show you that when I
click on this show heavy that time I'll
be able to see that heavy. JSX coming
over here. You want to see that I'm
clicking on show heavy. Right now you
see heavy. JSX. Now you saw heavy. JSX
and you are also seeing the rendered
part of heavy. JSX. Now if this heavy.
JSX is making an asynchronous API call
getting the data doing lot of
computation on this till this heavy. JS
is getting rendered completely attached
to the component tree. You would have
seen that fall back as it is very much
in memory and a very small component.
You are not seeing that fallback message
is happening very fast. But you got the
point right without lazy you are
downloading everything. There is no
separation in terms of performance. What
is heavy? What can I download
dynamically lazily now with lazy and
suspense you have that entire content. I
hope it was helpful. Now let's talk
about another technique called component
isolation. Now this is a good practice
part than a pure pattern because the
pattern of this we have covered in part
one already which is called memorization
but a good practice that want to
highlight. What we know we know react
rerenders children automatically when
parents render but with proper isolation
we can prevent this. Here is an example
which is a bad example. What do you see
over here? There is a dashboard
component which take two props. One is
user and other is statistics. It uses
three child component. One called user
card. Another called revenue. Another
called visitors. The user card use a
prop called users which uses this
particular value.
Has a prop called stats which you which
uses this stats value. Visitors doesn't
have any prop. Now in this situation if
the value of the stats changes this
dashboard renders
all the children redenders even the one
that doesn't depend on the stats
directly. Right? User card is going to
get rerendered. Visitors also going to
get rerender. Now how can I rewrite this
example little bit better way to save
from this rerendering? Let's see a good
example for this. The good example for
this would be this isolated dashboard.
Here also we have imported this revenue
user card visitors. But as you see I
have used memo from React passed this
component all together the user card and
the revenue which are props dependent
and got a memoized user card memoized
revenue and now I'm using the memoized
user card memoized revenue because of
this isolation what happened if the
stats changes now only this guy gets
rerendered this is never going to
rerender because user the input to this
am user card which is a memoized version
of user card is never changing so it is
memoized, it is cached, it is not going
to rerender. So we have learned this
technique of memorization in the part
one. I'm just showing certain good
practice of how you can isolate
components with memo so that it create
certain amount of render boundaries and
that's a pure win. I hope you find this
useful as well. By the way, are you
finding it helpful? If you find this
helpful, especially the part one, part
two, you should look into my
full-fledged course called React Design
Patterns, 15 days of React design
patterns, which is available for
absolutely free, taking you through all
the important design patterns that you
must know in React and apply them on my
YouTube channel. The link to that is in
the description of this video. All
right. So, the next one we are going to
talk about context optimization. What is
context? We know react context is pretty
powerful but can cause massive rerender
because it forms a chain right you
create a context to provider you provide
the value now wherever you want to use
the context in your component hierarchy
you can take the value out and you use
now something somewhere change can't
read your entire component hierarchy
which providers have wrapped so you have
to really be mindful of how you can
optimize your context Let's see one
example for that. Can you tell me
whether this is good or bad? Let me
explain this to you. I have created a
provider say user context provider. Now
this is coming from the user context and
I am giving value means I'm providing
value. One is the user data another the
theme information of my application and
what it is wrapping it is wrapping my
entire application. What do you think it
is good or bad? I would consider this as
bad example. Why? Because it is using
one big fat context. Imagine if theme
changes all the components that is
consuming user also redender. Now if the
user changes all the component that is
consuming theme is going to get
rerender. Now if these two values are
something which is partially be used
inside your application component
hierarchy you won't be passing things
like that. So what is a good practice?
The good practice would be splitting the
context. Now the same example you can
consider writing in this way like you
split them as user provider, you split
them as theme provider, you wrap the
part of your application tree where you
want to provide the user information,
you wrap the portion of your component
tree where you want to provide the theme
provider, right? It not necessarily it
has to wrap the application. It can go
inside the application and can wrap a
particular portion of the component tree
where you want to provide the user
provider. Now the first level of
optimization that you can do is first
split the context like I have splitted
the context with user provider and theme
provider separately. Here I was passing
the user value and theme value one big
fat context provider. Don't do that.
First is split. Second thing be mindful
whether user provider theme provider
need to wrap the entire application or
can I now go one more level down
identify what is that portion of my
component tree that only require my user
provider or my o provider or my
department provider whatever it is wrap
only that portion theme provider might
be something that should wrap the entire
application okay great but user provider
may be something which should not wrap
the entire application maybe the part of
the application so This is another
optimization technique that you have to
make sure that you keep in mind because
context is something that can leak lot
of performance issues in your
application if you're not mindful about
splitting them and use them
contextually. Have you seen some UI that
renders like say 100,000s
list elements and once you start
scrolling them you feel like very
sluggish is jank. Virtualization is a
technique that solve exactly that by
rendering only what's visible on the
screen. Okay. And then again when you
scroll it further you can load the next
set of item. Again you scroll it you can
load next set of item. So when you do
virtual scroll when you do pagionation
on those cases virtualization is a thing
that you must keep in mind. See the
thing is like what you show to the user
that's visible to your user. Why do you
want to unnecessarily bring things on
your browser, load your browser memory
that are not visible to user? Once you
want to make certain items visible to
your user, again bring that to your
browser, occupy your browser memory and
make it visible, make it render for your
user. So that's what virtualization
solves is another performance
optimization technique through which you
render only what's visible on your
screen. Let's learn by example. All
right, I have this demo for you. So this
has two mode. One is virtualization
mode, one is non virtualization mode.
Right now I am running on
nonverirtualization mode. I have a huge
list of array which I have rendered in a
nonverirtualization mode. It means that
I am rendering possible everything.
Though if I scroll down and I see like
I'm rendering only seven and if I scroll
down using this scroll I'll be rendering
more elements again and again. I'll make
it little smaller so that everything
come on the view. Yeah. Now using this
scroll I will try to scroll it. I find
it really sluggish. You see this you
know every time I try to scroll it is
really really sluggish. It is really
really slow. Now one thing that you can
see over here once you go up also it is
slow. If I just right click even my
right click is also taking some time. I
right clicked already. Still I'm not
getting now I'm getting inspect. Okay.
And click on inspect. Okay. And then on
the inspect bar you come over here
inside this div. If I just expand see
the number of divs that I have each of
the div is nothing but each row right.
So even after this many div this div
this is the seventh one this is the
eighth one which is not there in my
visible area but still I have loaded on
my DOM it's an extra thing I don't need
it I don't need it I don't have to go to
9,999
element because that's not visible guys.
So that's one problem. Second problem if
I go to the performance tab. This is a
performance tab. I'm sure that many of
you are not using. If you're not using,
you must learn about it. And if you want
a video from me how to use performance
tab, how to use React DevTools, comment,
let me know. I'm going to do that. All
right. So, what I'm going to do, I'm
going to refresh this and then I'm going
to run this recorder. Let's see. I'm
going to refresh this and I'm going to
run this recorder. The recorder is
running. In the meantime, it refreshes.
It bring my UI back stable. I'll stop
this. So it will load the trace in a
moment and you'll see something. It's
loading the trace. It will take some
time. It's loading now. It is processing
the trace now. Now it gave me some
result. Let's analyze this result. What
I want you to do, I want you to note
down these two things, these two
numbers. How much time it took for
scripting and how much time it took for
rendering. For scripting it is almost 3
seconds 3,275
millisecond. And for rendering 2.3
seconds 2361
millconds total it taken about 8 second
for rendering. 8 second for rendering
I'm probably rendering 10,000 array
elements in different ways right without
any virtualization. Now let's close
everything. Let's click on the virtual
mode. Use the virtual list. This is my
virtual list. It is actually showing a
lot of elements but because of my style
it is little bit unseen for you. But
this is showing. Great part. I can
scroll it pretty easily. I can scroll it
very easily. Very very easily I can
scroll it. There is no sluggishness at
all. There are some styling issues
that's fine but I can scroll it. So when
I inspect this inside this only a few 1
2 3 4 5 6 7 8 10 that's it. Rest of the
div not even created on my DOM. That's
the power of virtualization. If I come
down little bit with the scroll I
probably will be adding next 10. If I
scroll down a little bit more I'll be
adding next 10. I will go 10 by 10 by 10
using the virtualization technique. So
that means my initial load is pretty
fast. I'm not loading all unnecessary
things that are not visible. Here I'm
showing probably first six or seven but
I'm loading 10 is still okay. I'm
loading aggressively three more but
previously I was loading all 10,000
together which was a huge kill to my
performance. Okay. So that's the first
advantage of virtualization. Now next
thing I am going to do the same thing
with a performance thing. But for that I
have to refresh this application. And if
I refresh this application the default
mode will go to non-verirtual list.
Right? So I'll tweak my application
little bit. I'll go to virtualization
demo. Over here my default mode is
non-verirtual. I'll change that to
virtual. This one line of code change.
Now if I refresh also by default it will
be virtual. You see how fast it is. And
you see this red also got changed to
green. I have disabled the cache and
everything. It is how fast you can
actually imagine. But let us do the same
thing. Can you see scripting? It reduced
from 8 seconds to like 2 seconds. It has
reduced drastically. It has gone like
1/4 or below just because I have now
opted for virtualization. Let's take a
look into the code very quickly. So this
is my virtualization demo. I have had a
mode based on the link that you click
right non-verirtual versus virtual. I
basically render two different
component. One is the virtual list with
all the user data and there is called
non-verirtual list. Non-verirtual list
is a as usual thing. It's a uli element
where I take all these users loop
through it using map and show all the
information of the user. But for the
virtual list I'm using a library called
react window react window that helps us
in getting virtualization in react. From
that I use the component called list
which is given by react window to which
I pass this data and I pass few
configuration value and that's it. It
takes care of the virtualization. Right?
So whenever you have to show the long
list of data, always ensure that you opt
for virtual list, you opt for
virtualization, you have seen the
performance gain versus performance
degradation with the example that I have
showed to you. I hope it was helpful to
you. All this source code, whatever I
have used so far, it's on my GitHub
called github.com/tubbascript.
You can follow this organization if you
find it helpful. Under repositories you
will find 15 days of react design
patterns and inside this you will find
all this code inside day 11 because this
is when we are talking about the
performance patterns. If you like my
work don't forget to start this
repository as well. The next technique
is about the concurrent rendering using
transitions. Okay, React 18 introduced
something called concurrency in React to
keep the UI responsive. The problem that
you usually face when you type into a
search box like this that filters among
thousands of elements, 10 thousands
element, 100,000 element, your UI
freezes, your keystrokes lag, your
browser's main thread blocks. That's
where React came up with a solution
called a hook called use transition. Now
we going to see how we can use the hook
use transition and where exactly it is
useful. You can import the hook use
transition from React. The hook use
transition give you two things. One is a
function called start transition and a
state called is pending. The function
start transition tells react this
particular update is not urgent. Keep
the UI responsive while you are doing
everything that is defined inside this
function. For example, I have this text
box. Now this text box has two job. One,
if I type something, for example, E9, it
has to show E9. And it has another job
to pass this E9 to this below list so
that this list get filtered and I see
the updated result over here. Now if you
think about the user experience, you
don't want user to feel lagged when user
is typing each of the character over
here. It is okay if the processing of
this filter list takes certain time
because you might have to go to server
an API call, you have to process certain
algorithm, you have to come back and you
have to show the result. So this is
okay. You can probably show a loading
indicator or something to manage it. But
what if you type S and then it's a huge
lag before you type E. That's a bad
experience. So now among those two
operations like one is typing another is
filtering which one you think react
should prioritize of course the typing
into this box. So that means typing into
this box can be a faster operation and a
secondary operation non-urgent operation
would be filtering this particular list.
Now as I had explained what use
transition gives us it gives us a
function called start transition using
which you can define what is that that
you can tell react hey react take it you
know little bit relaxedly don't don't
really panic for this keep the UI
responsive while you are doing whatever
I have written inside the start
transition and when the start
transitions function execution is done
turn the is pending to false so that I
understand there is nothing pending from
you in the start transition function.
Now with the same example I have two
state one is the text another is the
query. The text is the input textbox
value which you want to keep updated
immediately. That's the reason if you
see in the handle change whenever
somebody typing I'm immediately calling
the updated function to update the text.
Fantastic. But filtering the list it
depending on something called a query
right because if you see this query this
is where my heavy list is getting
computed okay I'm passing this query now
setting this query value what will be
the query value based on which I am now
filtering my heavy list is inside the
start transition function so the start
transition function is marking this
heavy update as non-urgent updating
query triggers expensive filtering plus
rendering that and all can be marked as
non-urgent for me. I hope this is clear
to you. So again, if you want to get
much more deeper in concurrency how use
transition internally works, I have
created a video only for that only for
that purpose. You can take a look into
that. Again, I provided the link to that
video in the description of this video.
It will be helpful, I'm sure. Just like
use transition, React gives us one more
fantastic hook. It's called use deferred
value. Sometime people confuse between
use transition and use default value.
Let me explain. Both use transition and
use default value. Are react hook used
for performance optimization by marking
certain operation of the updates as low
priority. In terms of the demo that we
have done for use transition, you know
setting the query value that in turn
does the filtering we marked as low
priority item. Correct? But setting the
text on the input box, it is an usual
high priority item. Now purpose for use
deferred value and use transition is
same but how they do it is where it
differs both leverage reacts concurrent
feature but the primary difference is
what exactly they control. The use
transition hook what we have seen before
controls the state update function. If
you remember in the use transition demo
if I have to open it again we were
controlling the state transition
function of set query using the start
transition. Right? Whatever we write
inside the start transition function
that is kind of deferred that is a low
priority item. So here what we control
we control the state update function
itself. But in case of use deferred if
you see the usage of use deferred value
here you control the value that result
from the state update. Okay there you
are controlling the function itself.
Here you control the value. So what is
happening in this case? Almost similar
kind of application. The text which is
used in the input element it means that
text update on each keystroke must be
instant. The deferred text which is
computed out of the text and it's a
deferred value which means it's a
secondary citizen. React is not going to
look into it as a high priority. This
deferred text is used for filtering my
product. So I could have done the same
thing using use transition. In that case
inside my start transition I would have
had another state called say query or
set query. Set query is what I would
have marked as a secondary priority
thing. But if I want to do it with the
value itself I can use something called
use deferred value. So use deferred
value and use transition sometime people
confuses. There's no confusion. Okay. So
this is what the differences are and
another way where you can optimize your
performance. Our performance
optimization video won't be complete
without talking about this. So, React
uses keys to match the old and new
elements, right? We know about the
virtual DOM. We probably know about the
fiber framework and etc. Now, the keys
are a very important element in React.
Now, here something is very bad. We have
used index as a key. What is bad? Adding
or removing item shift indexes. React
thinks entries have changed. it break
the memorization causes unnecessary DOM
recreation. So this is another thing
people take lightly. Please don't do it.
The right approach, the right way of
doing this would be use an ID from your
data from your data structure which is
unique and use that. So this is stable
key. What you should be using when
you're iterating through a list in
React. Stable keys prevent React from
destroying and recreating the nodes.
Helps in better reconciliation. That
means it's a faster UI. So this is
another thing, another technique that
you have to keep in mind. We're almost
at the end of the part two. We have
spoke about a lot of optimizations but
it is not complete without talking about
some of the tools. We have seen the
usage of a few tools in the part two but
let me talk through a few tools that you
should explore. You must explore. One is
definitely React developer tools. It has
a very very strong potential and
documentation of React has captured it
very well step by step how you should be
using it. Please go ahead take a look
explore it how to install how to use it.
So React developer tools is one thing.
Second thing there is something called
React performance tracks. This is
something you should be looking into for
understanding scheduleuler the cascading
updates how components are getting
rendered all the aspects of it. Again
this documentation is very extensive.
Take a look into it. And then there is
another tool called React scan which I
use very often to see like what part of
my React application is unnecessary
getting rerender. Catch that guy and try
to fix it. So these are some of the
tools. I'm sure like it will be very
handy for you. As this video and the
previous one was very focused on React
design patterns and on performances. I
didn't cover these tools in depth. But
if you think that I should be making a
video covering the usage of each of
these tool, their right use cases in
depth. You know what to do. Post a
comment. Let me know if there are more
ask. It's a great motivation for me to
make again. And by the way, if you don't
want to miss any of those updates,
please follow Tapascript because that's
where I create awesome content, lot of
deep content taking lot of time. I'm
sure you're going to love them. So
please follow Tapascript. You know that
none of my session gets over without the
task. In the part one of the performance
patterns video, I had given you few
task. Let's skip them. I'm skipping them
because I've already explained this to
you before. Now the new task are remove
unnecessary use memo and use call back.
So there is a product card where I have
used use call back use memo. You have to
gain performance by removing them. You
know what to do if you have seen this
session. What React provides you from
React 19 to automatically memorize your
component. You know that. So use that.
These are the assignments. Remove
unnecessary memorization. Explain why
React compiler handle these cases.
Identify when memorization is still
required and lazy load a country
drop-down. Build a form with the fields
like name, email, and the country drop
down with 250 countries. Assignment.
Move the country selector into a
separate lazy loaded component. Show a
custom loaded like a spinner. And then
measure the initial bundle size with the
lazy component versus non- lazy factor
of it. And then on the splitting context
of the context optimization, let's see
how this big context where you have
user, theme, cart, local everything
together. How can you break them into
different context? Maybe user, theme,
cart, local, whatever you can think of
and then split it. So these are the new
three tasks that I have given. You can
do it. You can also think of task around
virtualization. Take a bigger list. How
to virtualize using react window or any
other solutions or your own solutions.
You can actually try that. So these are
the task. Please complete. Hey folks,
how was it? I hope it was helpful to
you. I'm super super happy completing
part one and part two of performance
patterns. I hope you find it helpful.
The list of performance techniques, the
good practices, the best way of handling
performance, whatever you have
discussed, please note them down. Take a
good look into them and see where you
can apply them in your day-to-day life.
Before I end, one word of wisdom. Don't
try to optimize performance of something
which is already working great.
Performance optimization is required
only when you found with the feedback
whether the feedback is yours, feedback
is from your QA team, feedback is from
your customer or the possibility where
the performance degradation might
happen. Then only pick up the technique
among all these things that we have
learned which is applicable and optimize
the performance of your application. I
wish all this learning stay with you and
you become a champion developer of
tomorrow. If you want to catch up more,
please catch up React design patterns
course which is for free available for
free on Tapascript channel. Follow
Tapascript for future content, future
updates. You won't be disappointed. Take
a great care of yourself. Stay tuned.
We'll be coming back again with some
great content in the future. Bye-bye.
React makes it easy to build UIs, but building fast React apps is a different skill altogether. In this hands-on, real-world React Performance Optimization crash course, you’ll learn how React actually re-renders, why your app slows down, and which performance patterns truly matter in production — not just theory, but battle-tested techniques used by senior engineers. This video is about knowing what to optimize, when to optimize, and how to do it right. This course was created by @tapasadhikary 📚 Resources - Check out the React Hooks Cheatsheet: https://www.tapascript.io/books/react-hooks-cheatsheet - tapaScript YouTube Channel: https://youtube.com/tapasadhikary - All my articles, handbooks on freeCodecamp: https://www.freecodecamp.org/news/author/atapas/ - Join my FREE Course, 40 Days of JavaScript: https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu - Join my FREE Course, 15 days of React Design patterns: https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC ⭐️ Chapters ⭐️ - 0:00:00 Performance Patterns - 0:01:16 What’s in Part 1? - 0:01:37 Re-Rendering in React - 0:05:16 Memoization - 0:07:44 The memo() - 0:12:08 The useCallback() - 0:20:33 the useMemo() - 0:28:07 The Derived State - 0:33:38 Debouncing - 0:41:27 Throttling - 0:46:32 Tasks from Part 1 - 0:48:10 Advanced Patterns - 0:49:11 What’s in Part 2? - 0:50:21 React Compiler - 1:00:11 Lazy Loading & Suspense - 1:11:31 Component Isolation - 1:13:35 Context Optimizations - 1:16:57 Virtualization - 1:23:46 Concurrency and useTransition() - 1:27:41 Deferred Value - 1:30:01 List and Keys - 1:31:01 Tools - 1:32:37 Tasks from Part 2 - 1:34:08 One Word of Wisdom 🤝 Connect with Tapas - Subscribe to my YouTube Channel: https://www.youtube.com/tapasadhikary - Connect on LinkedIn: https://www.linkedin.com/in/tapasadhikary/ - Follow on X: https://twitter.com/tapasadhikary - Check out my work on GitHub: https://github.com/atapas - Follow tapaScript on GitHub: https://github.com/tapascript - Join tapaScript Discord: https://discord.gg/ux9BchWEW3 ❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp 🎉 Thanks to our Champion and Sponsor supporters: 👾 @omerhattapoglu1158 👾 @goddardtan 👾 @akihayashi6629 👾 @kikilogsin 👾 @anthonycampbell2148 👾 @tobymiller7790 👾 @rajibdassharma497 👾 @CloudVirtualizationEnthusiast 👾 @adilsoncarlosvianacarlos 👾 @martinmacchia1564 👾 @ulisesmoralez4160 👾 @_Oscar_ 👾 @jedi-or-sith2728 👾 @justinhual1290 -- Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://freecodecamp.org/news