Node.js: Compression Gzip?

90

Est-ce que je me trompe en trouvant que Node.js ne fait pas de compression gzip et qu'il n'y a aucun module là-bas pour effectuer la compression gzip? Comment peut-on utiliser un serveur Web sans compression? Qu'est-ce que j'oublie ici? Dois-je essayer de porter l'algorithme vers JavaScript pour une utilisation côté serveur?

SnickersAreMyFave
la source

Réponses:

74

Node v0.6.x a maintenant un module zlib stable dans le noyau - il y a également quelques exemples sur la façon de l'utiliser côté serveur dans la documentation.

Un exemple (tiré de la documentation):

// 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
la source
1
J'ai rencontré un problème avec Internet Explorer qui n'aimait pas l'en-tête zlib que j'ai résolu en utilisant 'createDeflateRaw' au lieu de 'createDeflate'
marquez le
60

Si vous utilisez Express , vous pouvez utiliser sa méthode de compression dans le cadre de la configuration:

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

Et vous pouvez en trouver plus sur compress ici: http://expressjs.com/api.html#compress

Et si vous n'utilisez pas Express ... Pourquoi pas, mec?! :)

REMARQUE: (merci à @ankitjaininfo) Ce middleware devrait être l'un des premiers que vous «utilisez» pour vous assurer que toutes les réponses sont compressées. Assurez-vous que cela est au-dessus de vos routes et de votre gestionnaire statique (par exemple, comment je l'ai ci-dessus).

REMARQUE: (merci à @ ciro-costa) Depuis express 4.0, le express.compressmiddleware est obsolète. Il a été hérité de connect 3.0 et express n'inclut plus connect 3.0. Vérifiez Express Compression pour obtenir le middleware.

Milimétrique
la source
3
Voter sans commentaire? Faites-moi savoir pourquoi et j'espère que je pourrai améliorer la réponse. Ou n'hésitez pas à modifier vous-même.
Milimetric
2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Assurez-vous que cela est au-dessus de vos routes et de votre gestionnaire statique
ankitjaininfo
14
Désormais, le express.compressmiddleware (hérité de connect 3.0 <) est obsolète (depuis express 4.0) car il n'inclut plus connect 3.0 <. Vérifiez github.com/expressjs/compression pour obtenir le middleware.
Ciro Costa
2
à "Pourquoi pas, mec?!", les graphiques de cette page comparant http brut et framework express peuvent vous donner une raison. express le ralentit un peu raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis
:) C'était censé être un peu ironique. En fait, je n'aime pas express, il y a beaucoup plus de choses que j'aurais aimé faire et beaucoup plus de vernis que j'aurais aimé. Mais ça marche assez bien, je suppose, jusqu'à ce que quelque chose d'autre l'éclipse.
Milimetric
43

1- Installer la compression

npm install compression

2- Utilisez-le

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

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

compression sur Github

CoyBit
la source
1
comment vérifier si les assest statiques sont gzip ou non!
Rizwan Patel
mes images ne sont pas gzippées
Jeson Dias
en fait, vous devriez utiliser ce middleware lorsque vous envoyez de gros fichiers JS / CSS ou de gros fichiers JSON .. l'utilisation de ce middleware ne vous apportera aucun avantage, mais consommera plus de ressources cpu. @JesonDias
Shyam
@JesonDias vous ne devriez pas gzip d'images car JPEG inclut déjà un algorithme de compression qui fonctionne bien mieux pour les images que gzip. gzip est plus pour les trucs basés sur du texte.
user3413723
33

De manière générale, pour une application Web de production, vous souhaiterez placer votre application node.js derrière un proxy inverse léger tel que nginx ou lighttpd. Parmi les nombreux avantages de cette configuration, vous pouvez configurer le proxy inverse pour effectuer une compression http ou même une compression tls, sans avoir à changer le code source de votre application.

Yfeldblum
la source
ne laissez pas le nœud servir les fichiers statiques, laissez le proxy s'occuper de la compression, trouvez que c'est la meilleure pratique dans prod-env, vous voudrez peut-être utiliser nginx ou lighty de toute façon pour éviter que votre usr root n'exécute le nœud sur le port 80
ezmilhouse
En fonction de l'utilisation, je considérerais vraiment que c'est la bonne réponse.
prasanthv
@ezmilhouse Même si vous avez un proxy, votre serveur node.js doit toujours servir ces fichiers statiques au proxy, et il n'y a aucune raison de gaspiller de la bande passante même dans les tuyaux à l'intérieur de la même machine.
BT
8

Bien que vous puissiez gzip en utilisant un proxy inverse tel que nginx, lighttpd ou en vernis. Il peut être avantageux d'avoir la plupart des optimisations http telles que gzipping au niveau de l'application afin que vous puissiez avoir une approche beaucoup plus granulaire sur les actifs à gzip.

J'ai en fait créé mon propre module gzip pour expressjs / connect appelé gzippo https://github.com/tomgco/gzippo bien que nouveau, il fasse le travail. De plus, il utilise node-compress au lieu de générer la commande unix gzip.

Tomgco
la source
3
J'utilise gzippo sur un petit serveur web node.js maintenant, bonne chose!
bosgood
1
comment vérifier si gzip est appliqué aux assests statiques?
Rizwan Patel
4

Même si vous n'utilisez pas express, vous pouvez toujours utiliser leur middleware. Le module de compression est ce que j'utilise:

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
la source
3

Alors que d'autres l'ont souligné à juste titre en utilisant un serveur Web frontal tel qu'il nginxpeut gérer cela implicitement, une autre option consiste à utiliser l' excellent proxy node-http-proxy de nodejitsu de pour servir vos actifs.

par exemple:

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

Cet exemple démontre un soutien pour la compression gzip grâce à l'utilisation du middleware de connexion Module: connect-gzip.

cavalcade
la source
3

Pour compresser le fichier, vous pouvez utiliser le code ci-dessous

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

Pour décompresser le même fichier, vous pouvez utiliser le code ci-dessous

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
la source
J'adorerais voir un texte descriptif dans cette réponse! Bien que vos extraits de code puissent répondre à la question, il est recommandé d'inclure des explications pour le TO et le reste du monde pour comprendre pourquoi il répond à la question.
Clijsters
2

Et ça ?

node-compress
Un module de compression / gzip de streaming pour node.js
Pour l'installer, assurez-vous que libz est installé et exécutez:
node-waf configure
node-waf build
Cela placera le module binaire compress.node dans build / default.
...

Shay Erlichmen
la source
2

Il existe plusieurs middlewares Gzip pour Express, KOA et autres. Par exemple: https://www.npmjs.com/package/express-static-gzip

Cependant, Node est terriblement mauvais pour effectuer des tâches gourmandes en CPU comme gzipping, terminaison SSL, etc. À la place, utilisez un `` vrai '' service middleware comme nginx ou HAproxy, voir la puce 3 ici: http://goldbergyoni.com/checklist-best- pratique-du-nœud-js-en-production /

Yonatan
la source
2

À partir d'aujourd'hui, epxress.compress()semble faire un travail brillant à ce sujet.

Dans n'importe quelle application express, il suffit d'appeler this.use(express.compress());.

Je dirige personnellement une locomotive sur un express et cela fonctionne à merveille. Je ne peux pas parler d'autres bibliothèques ou frameworks construits sur express, mais tant qu'ils respectent la transparence totale de la pile, tout devrait bien se passer.

Crispen Smith
la source
2
Cela n'a pas vraiment de nouvelles informations, cela duplique cette réponse: stackoverflow.com/a/14341423/1355166
gcochard
1

Cela fait quelques bons jours avec node, et vous avez raison de dire que vous ne pouvez pas créer de serveur Web sans gzip.

Il y a pas mal d'options données sur la page des modules du wiki Node.js. J'ai essayé la plupart d'entre eux, mais c'est celui que j'utilise enfin -

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

La v1.0 est également sortie et a été assez stable jusqu'à présent.

Sudhanshu
la source
Je pense que votre commentaire est un peu trompeur. Bien que gzip soit courant dans les applications Web modernes, ce n'est pas une nécessité . Je pense que c'est parfaitement bien et conforme aux normes de ne pas l'utiliser.
Simon East
1

Utiliser la compression gzip

La compression Gzip peut réduire considérablement la taille du corps de la réponse et donc augmenter la vitesse d'une application Web. Utilisez le middleware de compression pour la compression gzip dans votre application Express. Par exemple:

var compression = require('compression');
var express = require('express')
var app = express()
app.use(compression())
Jai dewani
la source
Avons-nous besoin de décompresser la taille de la réponse à la taille du client?
Siddharth Sunchu