Node.js:Gzip压缩?


90

我发现Node.js不进行gzip压缩并且没有模块可以执行gzip压缩是我错了吗?谁能使用没有压缩功能的Web服务器?我在这里想念什么?我是否应该尝试将该算法移植到JavaScript以供服务器端使用?

Answers:


74

Node v0.6.x 现在在内核中具有稳定的zlib模块 -在文档中也有一些有关如何在服务器端使用它的示例。

一个例子(摘自文档):

// 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);

1
我遇到了Internet Explorer不喜欢zlib标头的问题,我使用'createDeflateRaw'而不是'createDeflate'解决了zlib标头
标记

60

如果使用Express,则可以在配置中使用其compress方法:

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

您可以在此处找到有关compress的更多信息:http : //expressjs.com/api.html#compress

而且,如果您不使用Express,那就干嘛呢?:)

注意:(感谢@ankitjaininfo)此中间件应该是您“使用”的第一个确保所有响应都被压缩的中间件。确保这在您的路由和静态处理程序之上(例如,我在上面如何拥有它)。

注意:(由于@ ciro-costa)自Express 4.0起,express.compress不推荐使用中间件。它是从connect 3.0继承的,表示不再包括connect 3.0。检查Express Compression以获取中间件。


3
没有评论的否决票?让我知道为什么,希望我能改善答案。或随时编辑自己。
Milimetric

2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. 确保这超出了您的路由和静态处理程序
ankitjaininfo 2014年

14
从现在开始,express.compress不推荐使用中间件(从connect 3.0 <继承)(自express 4.0起),因为它不再包含connect 3.0 <。检查github.com/expressjs/compression以获取中间件。
2014年

2
对于“为什么不,伙计?!”,此页上的图形将原始http和express框架进行了比较,可能会为您提供一个原因。表达放慢了它的速度raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis

:)这本来是有点舌头。我实际上不喜欢表达,我希望它做的事情更多,希望它做得更多。但我想它做得足够好,直到其他方面使它黯然失色。
Milimetric

43

1-安装压缩

npm install compression

2-使用它

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

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

在Github上压缩


1
如何检查静态资产是否为gzip!
Rizwan Patel

我的图像没有被压缩
Jeson Dias

实际上,当您发送大型JS / CSS文件或大型JSON文件时,您应该使用此中间件。使用该中间件不会给您带来好处,而是会消耗更多的CPU资源。@ JesonDias
Shyam,

@JesonDias,您不应该gzip图片,因为JPEG已经包含了一种压缩算法,该压缩算法比gzip效果更好。gzip更适合基于文本的东西。
user3413723

33

一般来说,对于生产Web应用程序,您将需要将node.js应用程序放在轻量级反向代理(例如nginx或lighttpd)后面。在此设置的众多好处中,您可以配置反向代理以执行http压缩甚至tls压缩,而无需更改应用程序源代码。


不要让节点提供静态文件,让代理处理压缩问题,并发现它是prod-env中的最佳实践,无论如何,您可能仍想使用nginx或lighty以避免根usr在端口80上运行节点
ezmilhouse

根据用法,我真的会认为这是正确的答案。
prasanthv

@ezmilhouse即使你有一个代理,你的node.js服务器仍然要服务于那些静态文件的代理,而且也没有理由,甚至在同一台机器内的管道浪费带宽。
BT

8

尽管您可以使用反向代理(例如nginx,lighttpd或使用清漆)来gzip。在应用程序级别进行大多数http优化(例如gzip压缩)可能是有益的,这样您就可以对gzip的资产采用非常细化的方法。

我实际上已经为expressjs / connect创建了自己的gzip模块,称为gzippo https://github.com/tomgco/gzippo,尽管它确实可以完成这项工作。另外,它使用节点压缩而不是生成unix gzip命令。


3
我现在在小型node.js网络服务器上使用gzippo,好东西!
bosgood 2012年

1
如何检查gzip是否应用于静态资产?
Rizwan Patel

4

即使您不使用Express,您仍然可以使用其中间件。该压缩模块是我使用的是什么:

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)

3

正如其他人正确指出的那样,使用诸如nginx可以隐式处理之类的前端Web服务器,另一种选择是使用nodejitsu出色的node-http-proxy来服务您的资产。

例如:

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

本示例通过使用connect middleware模块演示了对gzip压缩的支持connect-gzip


3

为了压缩文件,您可以使用以下代码

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.");

要解压缩同一文件,可以使用以下代码

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.");

希望在此答案中看到一些描述性文字!虽然您的代码段可能会回答问题,但是最好还是对TO和世界其他地方进行一些解释,以了解为什么它会回答问题。
Clijsters,2017年

2

怎么样这个

node-compress
一个用于node.js的流压缩/ gzip模块。
要安装,请确保已安装libz并运行:
node-waf configure
node-waf build
这会将compress.node二进制模块放入build / default。
...



2

截至今日, epxress.compress()似乎做得很出色。

在任何快递应用中,只需致电 this.use(express.compress());

我个人在Express上运行机车,并且运行效果非常好。我无法与其他在express之上构建的库或框架进行交流,但是只要它们尊重完整的堆栈透明性,您就可以了。


2
这实际上没有任何新信息,它重复了以下答案:stackoverflow.com/a/14341423/1355166
gcochard 2013年

1

与node一起度过了美好的一天,您应该说没有gzip就无法创建Web服务器。

Node.js Wiki的模块页面上提供了很多选项。我尝试了其中的大多数,但这是我最终使用的那个-

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

v1.0也已经发布,并且到目前为止非常稳定。


我认为您的评论有点误导。尽管gzip在现代Web应用程序中很常见,但这不是必需的。我认为这很好,并且不使用它也符合标准。
西蒙·伊斯特

1

使用gzip压缩

Gzip压缩可以大大减小响应主体的大小,从而提高Web应用程序的速度。在Express应用程序中使用压缩中间件进行gzip压缩。例如:

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

我们是否需要将响应大小解压缩为客户端大小?
Siddharth Sunchu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.