Node.js: compressão Gzip?

90

Estou errado em descobrir que o Node.js não faz compactação gzip e não há módulos disponíveis para realizar a compactação gzip? Como alguém pode usar um servidor web sem compressão? O que estou perdendo aqui? Devo tentar - suspiro - portar o algoritmo para JavaScript para uso do lado do servidor?

SnickersAreMyFave
fonte

Respostas:

74

O Node v0.6.x tem um módulo zlib estável no núcleo agora - há alguns exemplos de como usá-lo no lado do servidor nos documentos também.

Um exemplo (retirado dos documentos):

// 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);
Hughsk
fonte
1
Tive um problema com o Internet Explorer que não gostava do cabeçalho zlib, que resolvi usando 'createDeflateRaw' em vez de 'createDeflate'
marque
60

Se você estiver usando o Express , poderá usar o método de compactação como parte da configuração:

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

E você pode encontrar mais sobre compactação aqui: http://expressjs.com/api.html#compress

E se você não está usando o Express ... Por que não, cara ?! :)

NOTA: (graças a @ankitjaininfo) Este middleware deve ser um dos primeiros que você "usa" para garantir que todas as respostas sejam compactadas. Certifique-se de que está acima de suas rotas e manipulador estático (por exemplo, como eu tenho acima).

NOTA: (obrigado a @ciro-costa) Desde o express 4.0, o express.compressmiddleware está obsoleto. Ele foi herdado do Connect 3.0 e o Express não inclui mais o Connect 3.0. Verifique o Express Compression para obter o middleware.

Milimétrica
fonte
3
Votar sem comentar? Deixe-me saber o porquê e espero que eu possa melhorar a resposta. Ou sinta-se à vontade para editar você mesmo.
Milimétrico de
2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Certifique-se de que está acima de suas rotas e gerenciador estático
ankitjaininfo
14
De agora em diante, o express.compressmiddleware (que foi herdado do connect 3.0 <) está obsoleto (desde o express 4.0), pois não inclui mais o connect 3.0 <. Verifique github.com/expressjs/compression para obter o middleware.
Ciro Costa
2
para "Por que não, cara ?!", os gráficos nesta página comparando http bruto e estrutura expressa podem lhe dar um motivo. express retarda um pouco raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis
:) Isso era para ser um pouco irônico. Na verdade, não amo o Express, há muito mais coisas que eu gostaria que fizesse e muito mais polimento que eu gostaria que tivesse. Mas suponho que vai bem, até que algo mais o eclipse.
Milimétrico
43

1- Instale a compressão

npm install compression

2- Use

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

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

compressão no Github

CoyBit
fonte
1
como verificar se assest estático é gzip ou não!
Rizwan Patel
minhas imagens não estão sendo compactadas
Jeson Dias
na verdade, você deve usar este middleware quando estiver enviando grandes arquivos JS / CSS ou grandes arquivos JSON .. usar este middleware não trará benefícios, em vez disso, consumirá mais recursos de cpu. @JesonDias
Shyam
@JesonDias você não deve fazer gzip de imagens porque JPEG já inclui um algoritmo de compressão que funciona muito melhor para imagens do que gzip. gzip é mais para coisas baseadas em texto.
user3413723
33

De modo geral, para um aplicativo da web de produção, você desejará colocar seu aplicativo node.js atrás de um proxy reverso leve, como nginx ou lighttpd. Entre os muitos benefícios dessa configuração, você pode configurar o proxy reverso para fazer compactação http ou até mesmo tls, sem ter que alterar o código-fonte do aplicativo.

Yfeldblum
fonte
não deixe o nó servir arquivos estáticos, deixe o proxy cuidar da compressão, considere que é a melhor prática no prod-env, você pode querer usar o nginx ou lighty de qualquer maneira para evitar que seu nó raiz usr esteja executando na porta 80
ezmilhouse
Dependendo do uso, eu realmente consideraria essa a resposta certa.
prasanthv
@ezmilhouse Mesmo se você tiver um proxy, seu servidor node.js ainda precisa servir esses arquivos estáticos para o proxy, e não há razão para desperdiçar largura de banda mesmo em tubos dentro da mesma máquina.
BT
8

Embora você possa gzip usando um proxy reverso, como nginx, lighttpd ou em verniz. Pode ser benéfico ter a maioria das otimizações de http, como gzipar no nível do aplicativo, para que você possa ter uma abordagem mais granular sobre quais ativos fazer gzip.

Na verdade, criei meu próprio módulo gzip para expressjs / connect, chamado gzippo https://github.com/tomgco/gzippo, embora seja novo, ele faz o trabalho. Além disso, ele usa o node-compress em vez de gerar o comando unix gzip.

tomgco
fonte
3
Estou usando o gzippo em um pequeno servidor da web node.js agora, muito bom!
bosgood 01 de
1
como verificar se o gzip é aplicado a assests estáticos?
Rizwan Patel
4

Mesmo se você não estiver usando express, você ainda pode usar seu middleware. O módulo de compressão é o que estou usando:

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)
BT
fonte
3

Enquanto outros já apontaram o uso de um servidor da web front-end que nginxpossa lidar com isso implicitamente, outra opção é usar o excelente node-http-proxy do nodejitsu para servir seus ativos.

por exemplo:

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

Este exemplo demonstra o suporte para a compressão gzip através do uso de middleware de conexão do módulo: connect-gzip.

cavalgada
fonte
3

Para compactar o arquivo, você pode usar o código abaixo

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

Para descompactar o mesmo arquivo, você pode usar o código abaixo

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.");
Krish Jackman
fonte
Adoraria ver algum texto descritivo nesta resposta! Embora seus trechos de código possam responder à pergunta, é uma boa prática incluir algumas explicações para o TO e o resto do mundo para entender por que ele responde à pergunta.
Clijsters
2

Que tal isso ?

node-compress
Um módulo de compressão / gzip de streaming para node.js
Para instalar, certifique-se de ter o libz instalado e execute:
node-waf configure
node-waf build
Isso colocará o módulo binário compress.node em build / default.
...

Shay Erlichmen
fonte
2

A partir de hoje, epxress.compress() parece estar fazendo um trabalho brilhante nisso.

Em qualquer aplicativo expresso, basta ligar this.use(express.compress()); .

Estou dirigindo a locomotiva em cima do expresso pessoalmente e isso está funcionando perfeitamente. Não posso falar com nenhuma outra biblioteca ou estrutura construída sobre o Express, mas contanto que respeitem a transparência total da pilha, você não terá problemas.

Crispen Smith
fonte
2
Isso realmente não tem nenhuma informação nova, ele duplica esta resposta: stackoverflow.com/a/14341423/1355166
gcochard
1

Já se passaram alguns dias bons com o node, e você está certo em dizer que não pode criar um servidor web sem gzip.

Existem várias opções fornecidas na página de módulos no Wiki do Node.js. Eu tentei a maioria deles, mas este é o que finalmente estou usando -

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

v1.0 também foi lançado e tem estado bastante estável até agora.

Sudhanshu
fonte
Acho que seu comentário é um pouco enganador. Embora o gzip seja comum em aplicativos da web modernos, não é uma necessidade . Acho que é perfeitamente normal e compatível com os padrões não usá-lo.
Simon East
1

Use compressão gzip

A compactação Gzip pode diminuir muito o tamanho do corpo da resposta e, portanto, aumentar a velocidade de um aplicativo da web. Use o middleware de compactação para compactação gzip em seu aplicativo Express. Por exemplo:

var compression = require('compression');
var express = require('express')
var app = express()
app.use(compression())
Jai Dewani
fonte
Precisamos descompactar o tamanho da resposta no tamanho do cliente?
Siddharth Sunchu