Node.js: compressione Gzip?


90

Sbaglio a scoprire che Node.js non esegue la compressione gzip e non ci sono moduli là fuori per eseguire la compressione gzip? Come può chiunque utilizzare un server web che non ha compressione? Cosa mi manca qui? Devo provare, senza fiato, a portare l'algoritmo su JavaScript per l'utilizzo lato server?

Risposte:


74

Il nodo v0.6.x ha un modulo zlib stabile nel core ora - ci sono alcuni esempi su come usarlo sul lato server anche nei documenti.

Un esempio (tratto dalla documentazione):

// 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
Ho riscontrato un problema con Internet Explorer che non mi piaceva l'intestazione zlib che ho risolto utilizzando "createDeflateRaw" invece di "createDeflate"
segna il

60

Se utilizzi Express , puoi utilizzare il suo metodo di compressione come parte della configurazione:

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

E puoi trovare ulteriori informazioni sulla compressione qui: http://expressjs.com/api.html#compress

E se non stai usando Express ... Perché no, amico ?! :)

NOTA: (grazie a @ankitjaininfo) Questo middleware dovrebbe essere uno dei primi che "usi" per assicurarti che tutte le risposte siano compresse. Assicurati che questo sia al di sopra delle tue rotte e del gestore statico (ad esempio come lo ho sopra).

NOTA: (grazie a @ ciro-costa) A partire da Express 4.0, il express.compressmiddleware è deprecato. È stato ereditato da Connect 3.0 ed Express non include più Connect 3.0. Controlla la compressione rapida per ottenere il middleware.


3
Non votare senza un commento? Fammi sapere perché e spero di poter migliorare la risposta. Oppure sentiti libero di modificare te stesso.
Milimetrico

2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Assicurati che questo sia sopra le tue rotte e il gestore statico
ankitjaininfo

14
D'ora in poi il express.compressmiddleware (che è stato ereditato da connect 3.0 <) è deprecato (da express 4.0) poiché non include più connect 3.0 <. Controlla github.com/expressjs/compression per ottenere il middleware.
Ciro Costa

2
a "Perché no, amico ?!", i grafici in questa pagina che confrontano il raw http e il framework express possono darti una ragione. express lo rallenta un po ' raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis

:) Questo doveva essere un po 'ironico. In realtà non amo l'espresso, ci sono molte altre cose che vorrei che facesse e molto più lucido che avrei voluto che avesse. Ma suppongo che funzioni abbastanza bene, fino a quando qualcos'altro lo eclissa.
Milimetrico

43

1- Installa la compressione

npm install compression

2- Usalo

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

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

compressione su Github


1
come verificare se gli assest statici sono gzip o no!
Rizwan Patel

le mie immagini non vengono decompresse
Jeson Dias

in realtà dovresti usare questo middleware quando invii file JS / CSS di grandi dimensioni o file JSON di grandi dimensioni .. l'utilizzo di questo middleware non ti darà alcun vantaggio, ma consumerà più risorse della CPU. @JesonDias
Shyam

@JesonDias non dovresti gzip le immagini perché JPEG include già un algoritmo di compressione che funziona molto meglio per le immagini rispetto a gzip. gzip è più per roba basata su testo.
user3413723

33

In generale, per un'applicazione web di produzione, ti consigliamo di mettere la tua app node.js dietro un proxy inverso leggero come nginx o lighttpd. Tra i molti vantaggi di questa configurazione, è possibile configurare il proxy inverso per eseguire la compressione http o anche la compressione tls, senza dover modificare il codice sorgente dell'applicazione.


non lasciare che il nodo serva file statici, lascia che il proxy si occupi della compressione, trova che sia la migliore pratica in prod-env, potresti comunque voler usare nginx o lighty per evitare che il tuo usr root esegua il nodo sulla porta 80
ezmilhouse

A seconda dell'utilizzo, la considererei davvero la risposta giusta.
prasanthv

@ezmilhouse Anche se si dispone di un proxy, il server node.js deve comunque fornire quei file statici al proxy e non c'è motivo di sprecare larghezza di banda anche nelle pipe all'interno della stessa macchina.
BT

8

Sebbene sia possibile eseguire il gzip utilizzando un proxy inverso come nginx, lighttpd o in varnish. Può essere utile avere la maggior parte delle ottimizzazioni http come gzipping a livello di applicazione in modo da poter avere un approccio molto granulare su quale risorsa gzip.

In realtà ho creato il mio modulo gzip per expressjs / connect chiamato gzippo https://github.com/tomgco/gzippo anche se nuovo fa il lavoro. Inoltre utilizza node-compress invece di generare il comando gzip di unix.


3
Sto usando gzippo su un piccolo server web node.js ora, roba buona!
bosgood

1
come verificare se gzip è applicato agli assest statici?
Rizwan Patel

4

Anche se non utilizzi Express, puoi comunque utilizzare il loro middleware. Il modulo di compressione è quello che sto 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)

3

Mentre altri hanno giustamente sottolineato l'utilizzo di un server web front-end in nginxgrado di gestirlo implicitamente, un'altra opzione è usare l' eccellente node-http-proxy di nodejitsu per servire le tue risorse.

per esempio:

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

Questo esempio dimostra supporto per la compressione gzip attraverso l'utilizzo di middleware connect modulo: connect-gzip.


3

Per comprimere il file puoi usare il codice sottostante

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

Per decomprimere lo stesso file è possibile utilizzare il codice seguente

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

Mi piacerebbe vedere del testo descrittivo in questa risposta! Sebbene gli snippet di codice possano rispondere alla domanda, è buona norma includere alcune spiegazioni per il TO e il resto del mondo per capire perché risponde alla domanda.
Clijsters

2

Che ne dici di questo ?

node-compress
Un modulo di compressione / gzip di streaming per node.js
Per l'installazione, assicurati di aver installato libz ed esegui:
node-waf configure
node-waf build
Questo metterà il modulo binario compress.node in build / default.
...



2

Ad oggi, epxress.compress()sembra che stia facendo un ottimo lavoro.

In qualsiasi app express basta chiamare this.use(express.compress());.

Sto gestendo personalmente la locomotiva sopra l'espresso e funziona magnificamente. Non posso parlare con altre librerie o framework costruiti su express, ma fintanto che rispettano la piena trasparenza dello stack dovresti stare bene.


2
Questo in realtà non ha alcuna nuova informazione, duplica questa risposta: stackoverflow.com/a/14341423/1355166
gcochard

1

Sono stati alcuni giorni buoni con node e hai ragione a dire che non puoi creare un server web senza gzip.

Ci sono molte opzioni fornite nella pagina dei moduli sul Wiki di Node.js. Ho provato la maggior parte di loro, ma questo è quello che sto finalmente usando -

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

Anche la v1.0 è uscita ed è stata abbastanza stabile finora.


Penso che il tuo commento sia un po 'fuorviante. Sebbene gzip sia comune nelle moderne applicazioni web, non è una necessità . Penso che sia perfettamente a posto e conforme agli standard per non usarlo.
Simon East

1

Usa la compressione gzip

La compressione Gzip può ridurre notevolmente le dimensioni del corpo della risposta e quindi aumentare la velocità di un'app Web. Usa il middleware di compressione per la compressione gzip nella tua app Express. Per esempio:

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

Abbiamo bisogno di decomprimere la dimensione della risposta alla dimensione del client?
Siddharth Sunchu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.