Node.js is an asynchronous runtime built for I/O heavy applications, and much of our code will involve asynchronous callbacks.
In the previous recipes in this chapter, we've explored how to determine a performance issue, locate the issue to single synchronous JavaScript functions and optimize that function.
Sometimes, however, a performance bottleneck can be part of an asynchronous flow, in these scenarios it can be difficult to pinpoint where the performance issue is.
In this recipe, we'll cover profiling and optimizing an asynchronous performance problem in depth.