Js: Gzip 压缩?

我发现 Node.js 没有 gzip 压缩,也没有执行 gzip 压缩的模块,这是错误的吗?如何使用一个没有压缩的 Web 服务器?我错过了什么?我是否应该尝试将算法移植到 JavaScript 以供服务器端使用?

125630 次浏览

How about this?

node-compress
A streaming compression / gzip module for node.js
To install, ensure that you have libz installed, and run:
node-waf configure
node-waf build
This will put the compress.node binary module in build/default.
...

Generally speaking, for a production web application, you will want to put your node.js app behind a lightweight reverse proxy such as nginx or lighttpd. Among the many benefits of this setup, you can configure the reverse proxy to do http compression or even tls compression, without having to change your application source code.

It's been a few good days with node, and you're right to say that you can't create a webserver without gzip.

There are quite a lot options given on the modules page on the Node.js Wiki. I tried out most of them, but this is the one which I'm finally using -

https://github.com/donnerjack13589/node.gzip

v1.0 is also out and it has been quite stable so far.

Although you can gzip using a reverse proxy such as nginx, lighttpd or in varnish. It can be beneficial to have most http optimisations such as gzipping at the application level so that you can have a much granular approach on what asset's to gzip.

I have actually created my own gzip module for expressjs / connect called gzippo https://github.com/tomgco/gzippo although new it does do the job. Plus it uses node-compress instead of spawning the unix gzip command.

Node v0.6.x has a stable zlib module in core now - there are some examples on how to use it server-side in the docs too.

An example (taken from the docs):

// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
var raw = fs.createReadStream('index.html');
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}


// Note: this is not a conformant accept-encoding parser.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
if (acceptEncoding.match(/\bdeflate\b/)) {
response.writeHead(200, { 'content-encoding': 'deflate' });
raw.pipe(zlib.createDeflate()).pipe(response);
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.writeHead(200, { 'content-encoding': 'gzip' });
raw.pipe(zlib.createGzip()).pipe(response);
} else {
response.writeHead(200, {});
raw.pipe(response);
}
}).listen(1337);

While as others have right pointed out using a front end webserver such as nginx can handle this implicitly, another option, is to use nodejitsu's excellent node-http-proxy to serve up your assets.

eg:

httpProxy.createServer(
require('connect-gzip').gzip(),
9000, 'localhost'
).listen(8000);

This example demonstrates support for gzip compression through the use of connect middleware module: connect-gzip.

If you're using Express, then you can use its compress method as part of the configuration:

var express = require('express');
var app = express.createServer();
app.use(express.compress());

And you can find more on compress here: http://expressjs.com/api.html#compress

And if you're not using Express... Why not, man?! :)

NOTE: (thanks to @ankitjaininfo) This middleware should be one of the first you "use" to ensure all responses are compressed. Ensure that this is above your routes and static handler (eg. how I have it above).

NOTE: (thanks to @ciro-costa) Since express 4.0, the express.compress middleware is deprecated. It was inherited from connect 3.0 and express no longer includes connect 3.0. Check Express Compression for getting the middleware.

As of today, epxress.compress() seems to be doing a brilliant job of this.

In any express app just call this.use(express.compress());.

I'm running locomotive on top of express personally and this is working beautifully. I can't speak to any other libraries or frameworks built on top of express but as long as they honor full stack transparency you should be fine.

1- Install compression

npm install compression

2- Use it

var express     = require('express')
var compression = require('compression')


var app = express()
app.use(compression())

compression on Github

Even if you're not using express, you can still use their middleware. The compression module is what I'm using:

var http = require('http')
var fs = require('fs')
var compress = require("compression")
http.createServer(function(request, response) {
var noop = function(){}, useDefaultOptions = {}
compress(useDefaultOptions)(request,response,noop) // mutates the response object


response.writeHead(200)
fs.createReadStream('index.html').pipe(response)
}).listen(1337)

For compressing the file you can use below code

var fs = require("fs");
var zlib = require('zlib');
fs.createReadStream('input.txt').pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'));
console.log("File Compressed.");

For decompressing the same file you can use below code

var fs = require("fs");
var zlib = require('zlib');
fs.createReadStream('input.txt.gz')
.pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt'));
console.log("File Decompressed.");

There are multiple Gzip middlewares for Express, KOA and others. For example: https://www.npmjs.com/package/express-static-gzip

However, Node is awfully bad at doing CPU intensive tasks like gzipping, SSL termination, etc. Instead, use a ‘real’ middleware services like nginx or HAproxy, see bullet 3 here: http://goldbergyoni.com/checklist-best-practice-of-node-js-in-production/

Use gzip compression

Gzip compressing can greatly decrease the size of the response body and hence increase the speed of a web app. Use the compression middleware for gzip compression in your Express app. For example:

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