6 Easy Ways to Speed Up Express

Introduction

Express is by far the most popular web framework for Node.js thanks to its simple API, available plugins, and huge community. Thanks to the community, there is no shortage of documentation and examples on how to use the core Express API, which is great, but it's not always immediately clear how to improve the performance of your web application as it grows. Here I'll show you some of the easiest and most effective ways to improve the performance of your Express apps.

gzip Compression

gzip compression isn't anything new to web servers, but it's an easy thing to forget about, especially when you're used to using frameworks that enable it by default. This is one of those improvements that is extremely easy to add, and it provides a great performance boost. Compressing your page content can reduce page size by up to 70%.

var compression = require('compression'); var express = require('express'); var app = express(); app.use(compression());

Run Express in Production Mode

By default, Express will run in development mode, which is easy to overlook, especially for those just starting out with Node.js/Express.

So, whats the difference between production and development mode anyway? Turns out, in development mode the view templates are read from a file for each request, whereas in production mode the templates are loaded once and cached. This is done so you can easily make changes on the fly without having to restart the app every time during development. In a production environment, however, this can greatly reduce your performance since you have to deal with slow file IO as compared to much faster RAM.

Lucky for you, getting Express in to production mode is easy. It's just a matter of setting an environment variable.

$ export NODE_ENV=production

Be careful with this method though. If the server restarts, you'll lose this environment variable and go back to using development mode. A more permanent solution is to set the variable within your .bash_profile :

$ echo export NODE_ENV=production >> ~/.bash_profile $ source ~/.bash_profile

Minify with Uglify

For just about every website, especially those with lots of styling and client-side functionality, static assets can be a huge drag on performance. Having to send over multiple JavaScript and CSS files for each request eventually takes its toll on your server, and that's not even considering the time the user has to wait for all the separate HTTP requests to finish on the client side.

To help mitigate this, you can use a utility package like Uglify to minify and concatenate your JavaScript and CSS files. Combine this with a task runner like Grunt and you'll easily be able to automate the process and not have to worry about it. A fairly capable Grunt file (using the grunt-contrib-uglify plugin) might look something like this:

module.exports = function(grunt) { grunt.initConfig({ uglify: { options: { banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */

' }, dist: { files: { 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] } } } }); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.registerTask('default', ['uglify']); };

Reduce Your Middleware

I'm not saying you should never use middleware, obviously it's necessary and there are many reasons to use middleware in your Express apps, but it's easy to go overboard and copy all the middleware you see other apps using. Look through your list of dependencies and decide if you really need everything you have installed (cookies, sessions, i18n, request loggers, etc).

In some cases you only need middleware packages for development, so you can easily disable these in production:

var express = require('express'); var debugMiddleware = require('my-debug-middleware'); var app = express(); if (process.env.NODE_ENV !== 'production') { app.use(debugMiddleware()); }

Increase Max Sockets

By default the Node.js HTTP server has a socket pool limit of only 5. This is a very conservative number and most servers can handle a much higher number of sockets than this.

Alternatively, you can allow as many sockets as possible:

var http = require('http'); var https = require('https'); http.globalAgent.maxSockets = Infinity; https.globalAgent.maxSockets = Infinity;

Edit: This only applies for Node v0.10 and older. As of v0.12, maxSockets (for both http and https ) is set to Infinity .

Use Cache-Control

You can set an HTTP header that will tell the user's browser to cache the content it just received. This is usally a good idea for static assets (JS, CSS, etc) that change infrequently. For assigning app-wide cache settings, use:

var express = require('express'); var app = express(); app.use(express.static(__dirname + '/public', { maxAge: 31557600 }));

This will assign the cache settings for everything in the public directory. For more fine-grained control, you can set caching based on individual requests/routes:

var express = require('express'); var app = express(); app.get('/index.html', function (req, res) { res.setHeader('Cache-Control', 'public, max-age=86400'); res.render('index.html'); });

Conclusion

Keep in mind that you can find some great tips by browsing open source websites, like the Ghost blogging platform. These applications are developed and used by thousands of people, so you can usually find some great useful snippets that you wouldn't hear about otherwise.

There are quite a few things you can do outside of Express to speed things up, so if you haven't already, check out Redis, Nginx, and other caching mechanisms to give your app a boost. Believe me, it's worth your time.

Have any more Express performance tips? Let us know in the comments!