6

I have read that I should be compressing requests to my Node server, so I used npm to install the compression module, added it with require() to my server.js, then passed it in as a function to app.use.

Then I looked at the network tab after, and I wanted to see how much the compression had saved me in kb. So I took the compression off, restarted my server, and it was the same amount of kb as with compression turned on?

Here is my server.js

var express = require('express'),
    app = express(),
    path = require('path'),
    apiRouter = require('./app/routes/api'),
    mongoose = require('mongoose'),
    compression = require('compression');

app.use(compression());
app.use(express.static('public'));
app.use('/api', apiRouter);

app.use('*', function(req, res) {
    res.sendFile(path.join(__dirname + '/public/index.html'));
});

mongoose.connect('mongodb://localhost/triviaattack');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    //Connected to DB successfully.

});

app.listen(1337);
JohnWick
  • 4,929
  • 9
  • 37
  • 74
  • Edited my question, accidentally posted the version of server.js without the compression module. Fixed. – JohnWick Jan 19 '16 at 08:42

3 Answers3

8

Compression does not work unless the client sends a "Accept-Encoding:gzip" request header. You can test the compression here.

Harsha Bhat
  • 718
  • 10
  • 25
  • Hi, any way to check this if I am running on localhost? Edit: Nm, I'll just check in the console if those are being sent. When I last checked, I don't think they were. – JohnWick Jan 19 '16 at 09:47
  • Yes you can do a curl on it (see here: http://stackoverflow.com/questions/9140178/how-can-i-tell-if-my-server-is-serving-gzipped-content ) or install a tool such as Fiddler. – Harsha Bhat Jan 19 '16 at 09:52
  • I can see in my chrome console that the request headers are being sent with the gzip header. It just confused me that the bytes transferred was the same with compression on and off, atleast according to the chrome console again. But maybe I will use fiddler, it is awesome and I'm familiar with it. – JohnWick Jan 19 '16 at 09:54
  • this was my problem – chris Oct 26 '16 at 20:58
  • I have nodejs project in ES6 with babel, I have tried compression but don't work for me. I have tested all the cases explained here but not succeed. Any suggestion ! – Hardik Patel Jan 07 '22 at 10:46
5

When turning compression on and off for testing make sure that you're doing a hard reload in chrome dev tools or otherwise you'll get a 'not-modified' response that is not compressed.

Your example code is working for me!

saintedlama
  • 6,838
  • 1
  • 28
  • 46
  • Thanks. I closed chrome.exe and restarted it between testing. – JohnWick Jan 19 '16 at 09:48
  • I can now see that my bytes transferred has been cut in half. Awesome, not really sure what the issue was the first time I tested, but I think your response was the answer, so I marked it. – JohnWick Jan 19 '16 at 10:00
  • For assets like JS/CSS (that are usually cached), use "clear cache and hard reload". – Satya Kalluri May 06 '22 at 14:14
3

The compression middleware is a demanding horseman.

You need to set two things for it to work:

On the server, you need to specify a threshold size in bytes (default is 1024 (1kb) ) beyond which the response will be compressed. Start with 0:

app.use(compression({
    threshold: 0
}))

On the client, you need to set a header called Accept-Encoding to 'gzip' .

GET /mimic HTTP/1.1
Accept-Encoding: gzip
Host: localhost:3005

To decompress a response from the client side, you can do sth like this:

    const response = await axios.post(
        'http://localhost:3005/mimic', { headers: { "Accept-Encoding": "gzip" }, responseType: 'arraybuffer' })
    const xmlData = zlib.gunzipSync(response.data).toString()

In the above code, I am using the zlib and axios modules. zlib is a nodejs builtin module. There are other approaches if you're doing it from the browser. Notice that response.data is an array buffer.

Gilbert
  • 2,699
  • 28
  • 29