Improve React app performance with Throttling and Debouncing

Tram Ho

Question

In the process of building applications with ReactJS , we always have to pay attention to performance to avoid API calls , async requests , DOM updates , … too many times through React features like shouldComponentUpdate() , React.PureComponent , React.memo or Hooks ( useState() , useMemo() , useContext() , useReducer() , etc.

“Playable” code is a story, “good” code is another story.

 

In this article, we will look at a way to improve the performance of React apps without using any of the React features mentioned above, instead a general technique not only applied to React : Throttling. and Debouncing .

Let’s begin now 😽😽))

Start with the example

Search Box

Let’s start with an example:

In the above example, SearchBox , when you type a keyword in the input box, it will send an API request to get the list of users and display. This means that every 1 letter you type will send a request , if successful, the DOM will be update after the call to setState() .

Thus, when you type 10 characters, there will be 10 API requests and 10 updates DOM . That is we are considering only one user alone 🙃🙃. Even if the database stored local , update DOM after each character is also “costly”, isn’t it 😭😭

 

Use & attachment of events

Another example is the one we use in conjunction with the resize || event scroll . For the most part, a web page is scrolling ~1000 lần/s .

Suppose we have the following code:

This function will be called ~1000 lần/s xấu The worst case scenario is that the event handler must perform heavy DOM calculations and manipulations.

As you can see, after 9 9s the system will log out Scrolled !!! . If we scroll the body to 5000px , there will be 200+ events being called. Each event takes 9 seconds to finish. So after 9 * 200 = 1800s to complete all 200+ events. Therefore, it takes up to half an hour from start to finish. Surely the result will not be so sweet that the brouser will be “okay”, it may be lag or unresponsive 🤣🤣

Hmmm … realizing the problem here, right 😉😉

Let’s learn about base throttling & debouncing bit 😛😛

Throttling

Throttling enforces a maximum number of times a function can be called over time

 

Throttling is the adjustment of executing a certain function after a specified period of time has elapsed.

For example, “Only execute this function at most once in 100ms” . Or suppose we call a function at the rate of 1000 lần/20s . If we regulate to execute in every 500ms , then in 20s , the function will be executed in 40 lần/20s :

From 20000 down to 40 , significant yetaaaa 🤗🤗 To apply Throttling in React , we will use underscore , lodash libraries , RxJS & customize them individually .

underscore

The underscore library is a package on npm, used to modulate the component .

We can use in component as follows:

In the above code, the moderator handleInputThrottled() takes a callback , handleInput() (the function that needs to be modulated) and a timebox .

Returning to the example above, assuming the normal typing speed of a character is 200ms, typing 10 characters will cost 200 x 10 = 2000ms . The handleInput function will now only be called 2000 / 1000 = 2 times, instead of 10 times as before.

lodash

lodash is also a library that helps us with this problem.

For the first example:

It’s no different than replacing the throttle function on lodash with _.throttle on the underscore side 😺😺

RxJS

RxJS is Reactive Extensions in JS provides us with operators, including a throttling problem operator.

The first example will be handled as follows with RxJS :

We import throttle & BehaviorSubject from RxJS library. First, initializing an inputStream property is an BehaviorSubject instance . When you start typing the input, it is time to emit that value into the inputStream.

In componentDidMount , let inputStream go through a pipe with throttle(1000) (meaning RxJS will regulate inputStream every 1000ms ), then return a Observable , we subscrible to get that value.

Self written custom implementation

To better understand the throttling mechanism, perhaps we should write the throttling implementation ourselves

In the SearchBox component, we just need:

is okay 😁😁

Debouncing

Debouncing enforces that a function will not be called again until a certain amount of time has passed since its last call.

 

In Debouncing , it ignores all calls to a function and waits until the function stops being called for a specified amount of time. Regarding the application, the syntax is exactly the same as throtting , I can use lodash , underscore or RxJS :

You can also refer to a demo using debounce in lodash with Functional Component here .

Common cases

The case or use of throtting or deboucing can be mentioned as in the Game , especially action games that require pressing keys or performing actions such as shooting, speeding, … gamers have can press a key frequently (40 times in 20 seconds ie 2 times a second) but no matter how many gamers press the key to shoot, it will only fire once (say every second) .

In addition, the SearchBox case as above is often used throtting or deboucing quite a lot to restrict API calls , as a way to reduce the load for the server for example. 😺😺

Conclusion

Instead of having to invoke methods in React , Throtting or Deboucing applications, it is really a good solution to handle, improve performance, avoid cases of DOM-re-rendering unnecessary node .

Thank you for reading my article, giving me an upvote to be more motivated for upcoming topics ^^

See more related articles here . If you have additional comments or any questions related to this, please comment below for me!

Have a good day 🤗🤗🤗

Happy coding!

 

References: Medium

Share the news now

Source : Viblo