Key Takeaways
- Switching to production mode can significantly improve performance in Express applications, as this mode eliminates the logging tasks and exception stack traces that are present in development mode.
- Enabling GZIP compression in Express 4.x can shrink the HTTP payload, thus enhancing the performance. This can be done by installing the compression module and mounting it as the first middleware function.
- Removing unnecessary middleware, considering a simpler template engine, and effectively caching frequently-used variables can further optimize the performance of Express applications. A build tool like Gulp can be used to minify and concatenate HTML templates, CSS, and JavaScript files, and the use of session variables should be limited to avoid memory-related performance issues.
1. Switch to Production Mode
Express can run in several modes. By default, it presumes development mode which provides exception stack traces and other logging tasks. There is also a debugging mode which logs messages to the console, e.g.DEBUG=express:* node ./app.js
On your live server, you can noticeably improve performance by switching to production mode. This is achieved by setting the NODE_ENV
environment variable to production
. It can be set in the current session on Windows prior to launching your Express application:
set NODE_ENV=production
or Mac/Linux:
export NODE_ENV=production
Linux users can also set NODE_ENV
in a single line when launching:
NODE_ENV=production node ./app.js
Ideally, you should configure your environment by adding export NODE_ENV=production
to your ~/.bash_profile
or appropriate start-up script.
2. Enable GZIP
Express 4.x provides minimal functionality which can be enhanced with middleware. One of the less obvious missing features is GZIP compression which shrinks the HTTP payload so it can be expanded by the browser on receipt. To add GZIP, install the compression module using npm:npm install compression --save
(Depending on your setup, you may need to use sudo
on Mac/Linux — there are various ways to fix that.)
In your main application launch file, include the compression module:
var compression = require('compression');
then mount it as the first middleware function (prior to other Express .use
methods):
// GZIP all assets
app.use(compression());
3. Remove Unnecessary Middleware
If you generated a pre-built application using Express Generator or a similar process, remove any middleware modules you’re not using. For example, if you’re not using cookies you could remove the cookie-parser module or implement a simpler alternative using req.cookies and res.cookie. It may be possible to remove certain processes such as debugging output in production mode, e.g.if (app.get('env') !== 'production') {
// debugging middleware in development only
app.use(debuggerModule);
}
That said, it’s possibly best to keep serve-favicon
. Browsers request favicon.ico files frequently and the module improves caching.
4. Consider a Simpler Template Engine
Jade is the default template engine for many Express installations and it’s a great choice. However, if you’re happy writing your own HTML and just need basic interpolation and evaluation, consider a lightweight alternative such as doT which can be added as Express middleware using the express-dot-engine module. Alternatively, you can bypass the template engine for simpler responses, e.g.app.get('/hello', function (req, res) {
res.write('Hello!');
res.end();
});
Which ever template engine you use, always ensure the view cache is enabled:
app.set('view cache', true);
5. Remember to Cache!
Unlike most server-based applications, Node.js apps run permanently. You can therefore set frequently-used variables such as database connection objects once and re-use them during every request for every user. The concept can be extended as necessary. In general, the more high-use items you can cache the better performance will be. For example, presume your Express-based CMS application presented links to your five latest articles on the home page. That list could be generated and stored in a variable and only updated when a new article is posted.Bonus Quick Tips
Want a few more?…- Consider using nginx to serve static content and lighten the load on Node.js and Express.
- Use a build tool such as Gulp to minify and concatenate your HTML templates, CSS and JavaScript files.
- Limit the use of session variables. User session data is normally stored in memory which can lead to performance issues as usage grows. Consider using an ID only then fetch user information from a database during the request.
- Increase the maximum number of HTTP sockets from five to a higher number, e.g.
// use http/https as necessary http.globalAgent.maxSockets = 50;
- Where possible, call sequences of blocking operations in parallel rather than in sequence.
- Avoid using synchronous blocking calls in everything but application initialization.
- Always be conscious that code running for one user is blocking code running for every other user.
Frequently Asked Questions on Node.js Performance Tweaks
What are some common mistakes that can affect Node.js performance?
There are several common mistakes that can affect Node.js performance. One of the most common is blocking the event loop. Node.js is single-threaded, which means it can only do one thing at a time. If you block the event loop with a CPU-intensive task, it can’t handle any other requests until that task is finished. Another common mistake is not using the right data structures. For example, using an array when a set would be more efficient can significantly slow down your application. Lastly, not properly managing memory can also lead to performance issues. If your application uses too much memory, it can cause the system to start swapping, which can significantly slow down performance.
How can I use clustering to improve Node.js performance?
Clustering is a powerful technique that can significantly improve Node.js performance. It allows you to create multiple worker processes that can share the same server port. This means that you can take full advantage of multi-core systems, as each worker process can run on a separate CPU core. To use clustering in Node.js, you can use the built-in cluster module. This module allows you to easily create worker processes that all share the same server port.
How can I use caching to improve Node.js performance?
Caching is another effective way to improve Node.js performance. It involves storing the result of an operation in a cache so that the next time the operation is requested, the result can be retrieved from the cache instead of being recalculated. This can significantly reduce the amount of time it takes to process a request. There are several ways to implement caching in Node.js. One of the most common is to use a caching library like Redis or Memcached. These libraries allow you to easily store and retrieve data from a cache.
How can I use Gzip compression to improve Node.js performance?
Gzip compression can significantly reduce the size of the data that is sent over the network, which can improve Node.js performance. It works by compressing the data before it is sent over the network and then decompressing it on the client side. To use Gzip compression in Node.js, you can use the built-in zlib module. This module provides methods for compressing and decompressing data using Gzip.
How can I use performance hooks to measure Node.js performance?
Performance hooks are a feature of Node.js that allow you to measure the performance of your application. They provide a way to create a timeline of events, which can help you identify bottlenecks in your application. To use performance hooks in Node.js, you can use the built-in perf_hooks module. This module provides methods for creating and managing performance timelines.
How can I use load testing to improve Node.js performance?
Load testing is a technique that involves simulating a large number of users to test the performance of your application under heavy load. This can help you identify performance bottlenecks and ensure that your application can handle a large number of simultaneous users. There are several tools available for load testing Node.js applications, including Apache JMeter and Artillery.
How can I use profiling to improve Node.js performance?
Profiling is a technique that involves analyzing the performance of your application to identify bottlenecks. It provides detailed information about how your application is spending its time, which can help you identify areas that need optimization. There are several tools available for profiling Node.js applications, including the built-in profiler and third-party tools like Node Clinic and N|Solid.
How can I use asynchronous programming to improve Node.js performance?
Asynchronous programming is a key feature of Node.js that allows you to perform non-blocking operations. This means that your application can continue to handle other requests while waiting for an operation to complete. To use asynchronous programming in Node.js, you can use callbacks, promises, or async/await.
How can I use database optimization to improve Node.js performance?
Database optimization involves tuning your database queries to improve performance. This can involve things like using indexes to speed up queries, reducing the amount of data that is retrieved from the database, and using batch operations to reduce the number of database queries. There are several tools available for optimizing database performance in Node.js, including the built-in query optimizer and third-party tools like Sequelize and Mongoose.
How can I use code optimization to improve Node.js performance?
Code optimization involves making changes to your code to improve performance. This can involve things like removing unnecessary code, using more efficient algorithms, and optimizing your use of data structures. There are several tools available for optimizing code performance in Node.js, including the built-in V8 profiler and third-party tools like ESLint and Terser.
Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.