Simple tips to improve performance with Async/Await

Tram Ho

Are you a fan of the async / await syntax? Me too, in my opinion async / await is better than Promise chains . But I wonder if you have used it properly. Sometimes it can make your program run slower than expected. In this article, I will share something very important if you want to improve performance when using async / await and that is extremely easy to apply in your project.

Before Reading

Many JavaScript Devs love the async / await syntax. I think the reason why people like this syntax is because Promise hell , it keeps creating a chain when multiple then dots in a row.

async / await allows you to reduce or get rid of Promise hell by using the await keyword. But have you ever thought that this syntax can slow down your application when it is used in a non-optimal way?

So we have to do? Let’s talk about our options.

Helper Functions

Suppose there is a function called sleep . It will wait for the amount of time you want and is a basic Promise .

And we also have a fetch . function

The fetch pseudo-function takes an argument of type string and it is used to calculate the timeout. If we call fetch('/notice') , the timeout will be seven seconds because /notice has seven characters.

The basic situation and problem encountered for this example are

Now, we access the application; it is probably / . As soon as we access the main page, the code will try to load the data by typing fetch . (In this example, I use React )

We’ve done a fetch function before, which is a Promise . It has a string argument.

  • /banners → eight characters/eight second delay
  • /events → seven characters/seven seconds delay
  • /notices → eight characters/eight second delay

The graph shows the information above: /banner → 8 characters / 8 seconds delay / events → 7 characters / 7 second delay etc.

The total fetch time will be 23 giây because it waits for the current fetch to finish before calling the next one.

This structure is fine if fetch order is important. For example, we should fetch /login before /my-profile because that is members-only information.

What if there are more than five API that you need to fetch before rendering? The more APIs, the longer your users will wait before viewing the page.

Solution

The solution is very clear and simple.

The only difference from the previous version is that we no longer put the await keyword before fetch . Instead, we put it later. What happens after that?

Each fetch request will be sent to the server because none of them wait for a response before triggering the next fetch request.

Even though there is no extra work in componentDidMount in the example above, the longest maximum timeout would be just eight seconds.

Promise brings miracles

The reason that we can get huge benefit from changing a few lines of code is because of Promise . Basically, Promise is known as an API that works asynchronous . However, the real secret is hidden in the event queue.

Compare the Promise event queue with the normal event queue. The Promise event queue uses fetch commands.

JavaScript is single-threaded , as many of you already know. That means there is only one task running in the program at a time. Container, which is a type of queue that holds tasks until their turn is executed, is known as event queue or task queue this can vary depending on the document you are reading.

Examples of tasks that might be considered a normal task are console.log(1) , obj.foo() or anything similar that is not an asynchronous job.

Promise is an API asynchronous . At runtime, JavaScript sends a Promise task (or a Promise -based task) to the Promise event queue. And the tasks in the Promise queue must also wait their turn to be called. But note that any task in the Promise queue can only be pulled out and run if the normal task is completely empty.

Example of three promise queues: one for/banner, one for/event, and one for/notice.

Due to the await keyword on each line, the Promise queue cannot accept more tasks. First, fetch('/banners') is executed. The program waits for its response and queues the next fetch .

With this code, all three fetch can be viewed as stacked in the Promise queue in order from top to bottom. Those Promise will be pulled out and executed at roughly the same time (when the normal task queue is empty), but they don’t have to wait for the response of the previous fetch .

Demo

<iframe src=”https://codesandbox.io/embed/async-await-performance-vmo2q?fontsize=14&hidenavigation=1&theme=dark” style=”width:100%; height:500px; border:0; border-radius : 4px; overflow:hidden;” title=”async-await-performance” allow=”accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking” sandbox= “allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts” ></iframe>

Another example

The result will be:

Promise.all

You can also use Promise.all to solve the above problem (or Promise.allSettled in case you don’t care about failed request ).

Conclusion

Using async / await syntax makes our lives easier and happier, but we should use them well. Simply putting the await keyword somewhere can have very different consequences depending on where you put it.

Roundup

As always, I hope you enjoyed this article and learned something new.

Thank you and see you in the next posts!

If you find this blog interesting, please give me a like and subscribe to support me. Thank you.

Ref

Share the news now

Source : Viblo