Faster expressjs
Apps — Why is your nodejs
app slow
This blog explores common use cases that make expressjs
applications and for that matter some nodejs
applications, slow. We will take a different approach to only list known facts, and provide quick fixes whenever possible.
In this article we will talk about:
- Module loader is slow
- Modular layout improves performance
- Serving requests under 9 seconds
Even though this blogpost was designed to offer complementary materials to those who bought my Testing
nodejs
Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.
nodejs
Module Loader is slow
- Starting
nodejs
server is slow, or starting test cases is really slow. The code structure may be to blame. The leading cause of memory leak in GC is using anonymous callbacks. In case anonymous callbacks are really to blame, a quick and dirty technique to save a couple of milliseconds would be to name all, if not most anonymous functions — including promises, callbacks, and common handlers. require()
— thenodejs
module loader is really slow and may be to blame.require()
is synchronous, which means blocking when loading each module. The quick and dirty technique is to use as fewerrequire()
statements as possible. Alternatively, adding a caching module caching mechanism can solve the issue. There is a quick drop-in require replacement that Dr. Gleb Bahmutov, PhD put together: cache-require-paths.- Some utility functions are simply slow. To figure out the culprit, we either have to run a benchmarking test or are lucky enough and the community already identified some utilities that are really slow. That is the case of of
url-parse
(~> url-parse is deadly slow). Quick and dirty trick: find a performant alternative to the library that is really slow. In case of url-parse, there is a faster alternative: faster-url-parser. - Using
debug()
from the debugnodejs
debugging utility, instead ofconsole.log()
for debugging purposes. Quick and dirty trick: replace allconsole.log(x)
withdebug(x)
wherever possible, make sure to get rid of other slow synchronous loggers. > The major difference between debugging and logging is at a persistence level, or the way the application is supposed to use data it harvested during an execution period. Log messages are permanent and used for forensic purposes, debug messages are ephemeral and used for debugging purposes. - In case
console.log()
has been used for logging, usingwinston
, orbunyan
, for logging purposes instead of dumping messages to the console usingconsole.log()
may be a wise alternative. Quick and dirty trick: replace all logging with asynchronous stream-basedlogger.log()
instead ofconsole.log()
. - The previous was just the beginning. Here is a list of other articles that may help fixing some performance issues: 1) On IBM – Blog: Tips optimizing slow code in
nodejs
2) Onexpressjs
– Blog: Best practice performance. 3) Fournodejs
Gotchas that Operations Teams Should Know about - Before any performance improvement, it is better to start with a profiling session. Profiling code gives insights on how functions interact, helps identify which functions are mostly occupying the CPU.
- Profiling is hard. Luckily, there are good visualizations that put collected data to graphs the rest of us can read and understand. For that though, you will need to know how to read the flame chart. There are more introductory writings about Flame Graphs, and Flame Chart on – The Mozilla Developer Networks. The next article provides more insights on the CPU flame graphs. > There is a technique used to log profiles and visualize results in a sunburst diagram.
- Least but not last, there is Profiling slow
nodejs
apps using v8-profiler and Paul Irish quick introduction on How to debugnodejs
with Chrome DevTools.
Is it possible to include performance analysis in the development workflow?
Conclusion
In this article, we revisited reasons why some parts of nodejs
project may be slow. We also suggested measures to take to mitigate some of the common use cases. The format and size of this blog post barely scratch the surface. However, there are additional complementary materials in the “Testing nodejs
applications” book that can help understanding more on the subject.