Node.js: ¿compresión Gzip?

90

¿Me equivoco al encontrar que Node.js no realiza compresión gzip y que no hay módulos para realizar la compresión gzip? ¿Cómo puede alguien usar un servidor web que no tiene compresión? ¿Que me estoy perdiendo aqui? ¿Debería intentar, jadear, portar el algoritmo a JavaScript para su uso en el servidor?

SnickersAreMyFave
fuente

Respuestas:

74

El nodo v0.6.x tiene un módulo zlib estable en el núcleo ahora; también hay algunos ejemplos sobre cómo usarlo en el lado del servidor en los documentos.

Un ejemplo (tomado de los 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
fuente
1
Me encontré con un problema con Internet Explorer que no me gustaba el encabezado zlib que resolví usando 'createDeflateRaw' en lugar de 'createDeflate'
marque el
60

Si está utilizando Express , puede utilizar su método de compresión como parte de la configuración:

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

Y puedes encontrar más sobre comprimir aquí: http://expressjs.com/api.html#compress

Y si no estás usando Express ... ¡¿Por qué no, hombre ?! :)

NOTA: (gracias a @ankitjaininfo) Este middleware debería ser uno de los primeros que "use" para asegurarse de que todas las respuestas estén comprimidas. Asegúrese de que esté por encima de sus rutas y controlador estático (por ejemplo, cómo lo tengo arriba).

NOTA: (gracias a @ ciro-costa) Desde express 4.0, el express.compressmiddleware está obsoleto. Se heredó de connect 3.0 y Express ya no incluye connect 3.0. Consulte Express Compression para obtener el middleware.

Milimétrico
fuente
3
¿Votar en contra sin un comentario? Déjame saber por qué y espero poder mejorar la respuesta. O siéntase libre de editar usted mismo.
Milimétrico
2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Asegúrese de que esté por encima de sus rutas y controlador estático
ankitjaininfo
14
A partir de ahora, el express.compressmiddleware (que se heredó de connect 3.0 <) está en desuso (desde express 4.0) ya que ya no incluye connect 3.0 <. Consulte github.com/expressjs/compression para obtener el middleware.
Ciro Costa
2
a "¿Por qué no, hombre?", los gráficos de esta página que comparan http sin formato y el marco expreso pueden darle una razón. express lo ralentiza un poco raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis
:) Eso estaba destinado a ser un poco irónico. De hecho, no me encanta el expreso, hay muchas más cosas que desearía que hiciera y mucho más pulido desearía que tuviera. Pero lo hace bastante bien, supongo, hasta que algo más lo eclipsa.
Milimétrico
43

1- Instalar compresión

npm install compression

2- Úselo

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

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

compresión en Github

CoyBit
fuente
1
cómo comprobar si las pruebas estáticas son gzip o no!
Rizwan Patel
mis imágenes no tienen gzip
Jeson Dias
en realidad, debería utilizar este middleware cuando envíe grandes archivos JS / CSS o grandes archivos JSON ... el uso de este middleware no le dará ningún beneficio, sino que consumirá más recursos de la CPU. @JesonDias
Shyam
@JesonDias no deberías usar gzip en imágenes porque JPEG ya incluye un algoritmo de compresión que funciona mucho mejor para imágenes que gzip. gzip es más para cosas basadas en texto.
user3413723
33

En términos generales, para una aplicación web de producción, querrá poner su aplicación node.js detrás de un proxy inverso ligero como nginx o lighttpd. Entre los muchos beneficios de esta configuración, puede configurar el proxy inverso para realizar compresión http o incluso compresión tls, sin tener que cambiar el código fuente de su aplicación.

yfeldblum
fuente
no permita que el nodo sirva archivos estáticos, deje que el proxy se encargue de la compresión, considere que es la mejor práctica en prod-env, es posible que desee usar nginx o lighty de todos modos para evitar que su
usuario
Dependiendo del uso, realmente consideraría que esta es la respuesta correcta.
prasanthv
@ezmilhouse Incluso si usted tiene un proxy, el servidor Node.js todavía tiene que servir a los archivos estáticos al proxy, y no hay razón para desperdiciar ancho de banda incluso en tuberías dentro de la misma máquina.
BT
8

Aunque puede gzip usando un proxy inverso como nginx, lighttpd o en barniz. Puede ser beneficioso tener la mayoría de las optimizaciones de http, como gzip en el nivel de la aplicación, para que pueda tener un enfoque mucho más granular sobre los activos a gzip.

De hecho, he creado mi propio módulo gzip para expressjs / connect llamado gzippo https://github.com/tomgco/gzippo, aunque es nuevo que hace el trabajo. Además, usa node-compress en lugar de generar el comando gzip de Unix.

tomgco
fuente
3
Estoy usando gzippo en un pequeño servidor web node.js ahora, ¡buenas cosas!
bosgood
1
¿Cómo comprobar si gzip se aplica a evaluaciones estáticas?
Rizwan Patel
4

Incluso si no está usando Express, aún puede usar su middleware. El módulo de compresión es lo que estoy 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
fuente
3

Mientras que otros han señalado con razón el uso de un servidor web front-end como nginxpuede manejar esto implícitamente, otra opción es usar el excelente proxy node-http-de nodejitsu para servir sus activos.

p.ej:

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

Este ejemplo demuestra el apoyo a la compresión gzip a través del uso de middleware de conexión del módulo: connect-gzip.

cabalgada
fuente
3

Para comprimir el archivo, puede usar el siguiente código

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 descomprimir el mismo archivo, puede usar el siguiente código

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
fuente
¡Me encantaría ver un texto descriptivo en esta respuesta! Si bien sus fragmentos de código pueden responder a la pregunta, es una buena práctica incluir algunas explicaciones para que el TO y el resto del mundo comprendan por qué responde a la pregunta.
Clijsters
2

¿Qué tal esto ?

node-compress
Un módulo de streaming de compresión / gzip para node.js
Para instalar, asegúrese de tener libz instalado y ejecute:
node-waf configure
node-waf build
Esto pondrá el módulo binario compress.node en build / default.
...

Shay Erlichmen
fuente
2

A día de hoy, epxress.compress()parece estar haciendo un trabajo brillante al respecto.

En cualquier aplicación express solo llame this.use(express.compress());.

Estoy manejando una locomotora en la parte superior del expreso personalmente y esto está funcionando muy bien. No puedo hablar con otras bibliotecas o marcos creados sobre Express, pero siempre que respeten la transparencia de la pila completa, debería estar bien.

Crispen Smith
fuente
2
Esto realmente no tiene ninguna información nueva, duplica esta respuesta: stackoverflow.com/a/14341423/1355166
gcochard
1

Han sido unos buenos días con node, y tiene razón al decir que no puede crear un servidor web sin gzip.

Hay muchas opciones en la página de módulos en el Wiki de Node.js. Probé la mayoría de ellos, pero este es el que finalmente estoy usando:

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

La v1.0 también está disponible y se ha mantenido bastante estable hasta ahora.

Sudhanshu
fuente
Creo que tu comentario es un poco engañoso. Si bien gzip es común en las aplicaciones web modernas, no es una necesidad . Creo que está perfectamente bien y cumple con los estándares para no usarlo.
Simon East
1

Usar compresión gzip

La compresión Gzip puede disminuir enormemente el tamaño del cuerpo de respuesta y, por lo tanto, aumentar la velocidad de una aplicación web. Utilice el middleware de compresión para la compresión gzip en su aplicación Express. Por ejemplo:

var compression = require('compression');
var express = require('express')
var app = express()
app.use(compression())
Jai dewani
fuente
¿Necesitamos descomprimir el tamaño de la respuesta al tamaño del cliente?
Siddharth Sunchu