Node.js is an open source, cross-platform JavaScript runtime environment for server-side and networking applications. Node.js is built on top of the Google V8 JavaScript engine, which means Node.js applications are written in JavaScript and use a similar syntax as front-end JavaScript applications, including objects, functions, and methods. [58]
Node.js comes with a built-in library that allows applications to act as a web server. Thanks to its event-driven architecture and a non-blocking I/O API that optimizes an application’s throughput, Node.js excels when it comes to real-time communication. The following are advantages of Node.js: [58, 59, 60]
- It is very lightweight and fast.
- It is easy to configure and highly customizable.
- It comes with the npm package manager that contains 140.000+ packages that are available for free, and it handles dependencies excellently.
- It removes silos that existed between frontend and backend developers, making the development process more effective. Backend and frontend teams can be merged into one unit.
- It allows one to build the application in JavaScript “top-to-bottom”, even down to the database level if NoSQL DB that stores objects in JSON (like MongoDB or Cloudant) is used. This makes development and even hiring significantly easier.
- It is capable of handling a huge number of simultaneous connections with high throughput. Therefore, it excels in building fast and scalable network applications.
- It allows code to be reused across the client-side and server-side of the application.
- Even though Node.js is initially designed without threads, one can still take advantage of multiple cores and spawn child processes using ChildProcess API.
Blocking example
An example of blocking is how some web servers like ones in Java or PHP handle requests. If your code does something blocking, like reading something from the database, your code “stalls” at that line and waits for the operation to finish. In that period, your machine is holding onto memory and processing time for a thread that is not doing anything. In order to cater other requests while that thread has stalled depends on your setup. Your server can spawn more threads to cater the request or, if you have a load balancing setup, forwards requests to the next available instance. This instills more setup, more memory consumed, more processing.
Non-blocking example
In contrast, non-blocking servers like ones made in Node.JS, only use one thread to service all requests. This might sound counter-intuitive, but the creators designed it with the idea that the I/O is the bottleneck i.e. not computations. When requests arrive at the server, they are serviced one at a time. When the code serviced needs to query the DB for example, it sends off a request to the DB. However, instead of waiting for the response and stall, it sends the callback to a second queue and the code continues running. Now when the DB returns data, the callback gets queued in a third queue where they are pending execution. When the engine is doing nothing (stack empty), it picks up a callback from the third queue and executes it.
Node.js has one disadvantage – it is not designed for heavy computations as any CPU intensive operation annuls all of the throughput and any incoming request is blocked while the thread is busy crunching numbers.
“How it works under-the-hood is pretty interesting. Compared to traditional web-serving techniques where each connection (request) spawns a new thread, taking up system RAM and eventually maxing-out at the amount of RAM available, Node.js operates on a singlethread, using non-blocking I/O calls, allowing it to support tens of thousands of concurrent connections (held in the event loop). A quick calculation: assuming that each thread potentially has an accompanying 2 MB of memory with it, running on a system with 8 GB of RAM puts us at a theoretical maximum of 4000 concurrent connections, plus the cost of context-switching between threads. That is the scenario you typically deal with in traditional web-serving techniques. By avoiding all that, Node.js achieves scalability levels of over 1M concurrent connections.” [60]
Bibliography
[57] What is non-blocking or asynchronous I/O in Node.js? URL: http://stackoverflow.com/questions/10570246/what-is-non-blocking-orasynchronous-i-o-in-node-js (visited on 03/30/2015).
[58] A. Mardan. Practical Node.js: Building Real-World Scalable Web Apps. Apress, 2014. ISBN: 1430265957.
[59] About Node.js. URL: https://nodejs.org/about/ (visited on 03/30/2015).
[60] T. Capan. Why The Hell Would I Use Node.js? A Case-by-Case Tutorial. URL: http://www.toptal.com/nodejs/why-the-hell-would-i-use-node-js (visited on 03/30/2015).