Node.js: kompresja Gzip?

90

Czy mylę się, stwierdzając, że Node.js nie ma kompresji gzip i nie ma modułów do wykonywania kompresji gzip? Jak ktoś może korzystać z serwera WWW, który nie ma kompresji? Czego tu brakuje? Czy powinienem spróbować - zdyszać - przenieść algorytm do JavaScript do użytku po stronie serwera?

SnickersAreMyFave
źródło

Odpowiedzi:

74

Node v0.6.x ma teraz stabilny moduł zlib w rdzeniu - jest kilka przykładów, jak go używać po stronie serwera również w dokumentacji.

Przykład (zaczerpnięty z dokumentacji):

// 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
źródło
1
Napotkałem problem z Internet Explorerem, który nie lubił nagłówka zlib, który rozwiązałem, używając „createDeflateRaw” zamiast „createDeflate”
zaznacz
60

Jeśli używasz Express , możesz użyć jego metody kompresji w ramach konfiguracji:

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

Więcej na temat kompresji można znaleźć tutaj: http://expressjs.com/api.html#compress

A jeśli nie używasz Express ... Dlaczego nie, stary ?! :)

UWAGA: (dzięki @ankitjaininfo) To oprogramowanie pośredniczące powinno być jednym z pierwszych, które „używasz”, aby zapewnić skompresowanie wszystkich odpowiedzi. Upewnij się, że jest to powyżej twoich tras i obsługi statycznej (np. Jak mam to powyżej).

UWAGA: (dzięki @ ciro-costa) Od wersji Express 4.0 express.compressoprogramowanie pośredniczące jest przestarzałe. Został odziedziczony z Connect 3.0 i Express nie zawiera już Connect 3.0. Sprawdź Express Compression, aby uzyskać oprogramowanie pośredniczące.

Milimetryczny
źródło
3
Głos w dół bez komentarza? Daj mi znać, dlaczego i mam nadzieję, że mogę poprawić odpowiedź. Lub możesz samodzielnie edytować.
Milimetryczny
2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Upewnij się, że znajduje się on nad Twoimi trasami i statyczną obsługą
ankitjaininfo,
14
Od tej pory express.compressoprogramowanie pośredniczące (które zostało odziedziczone z connect 3.0 <) jest przestarzałe (od wersji Express 4.0), ponieważ nie zawiera już connect 3.0 <. Sprawdź github.com/expressjs/compression, aby uzyskać oprogramowanie pośredniczące.
Ciro Costa
2
do "Czemu nie, człowieku ?!", wykresy na tej stronie, porównujące surowy http i framework ekspresowy, mogą dać ci powód. express nieco go spowalnia raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis
:) To miało być trochę z przymrużeniem oka. Właściwie to nie lubię ekspresji, jest o wiele więcej rzeczy, które chciałbym, żeby to robiło i dużo więcej polerowania, które chciałbym mieć. Ale wydaje mi się, że robi to wystarczająco dobrze, dopóki coś innego go nie przyćmiewa.
Milimetryczny
43

1- Zainstaluj kompresję

npm install compression

2- Użyj go

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

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

kompresja na Githubie

CoyBit
źródło
1
jak sprawdzić, czy test statyczny jest gzipem, czy nie!
Rizwan Patel
moje obrazy nie są spakowane
Jeson Dias
w rzeczywistości powinieneś to oprogramowanie pośredniczące, gdy wysyłasz duże pliki JS / CSS lub duże pliki JSON. Korzystanie z tego oprogramowania pośredniego nie przyniesie korzyści, zamiast tego zużyje więcej zasobów procesora. @JesonDias
Shyam
@JesonDias nie powinieneś gzipować obrazów, ponieważ JPEG zawiera już algorytm kompresji, który działa znacznie lepiej dla obrazów niż gzip. gzip jest bardziej dla rzeczy tekstowych.
user3413723
33

Ogólnie rzecz biorąc, w przypadku produkcyjnej aplikacji internetowej będziesz chciał umieścić aplikację node.js za lekkim odwrotnym serwerem proxy, takim jak nginx lub lighttpd. Wśród wielu zalet tej konfiguracji można skonfigurować odwrotne proxy do kompresji http lub nawet kompresji tls bez konieczności zmiany kodu źródłowego aplikacji.

yfeldblum
źródło
nie pozwól węzłowi obsługiwać plików statycznych, pozwól proxy zająć się kompresją, uznaj to za najlepszą praktykę w prod-env, możesz i tak użyć nginx lub lighty, aby uniknąć działania węzła root usr na porcie 80
ezmilhouse
W zależności od zastosowania naprawdę uważam to za właściwą odpowiedź.
prasanthv
@ezmilhouse Nawet jeśli masz serwer proxy, serwer node.js wciąż musi służyć te pliki statyczne do serwera proxy, a nie ma powodu, aby tracić przepustowości nawet w rurach wewnątrz tej samej maszynie.
BT
8

Chociaż możesz użyć gzipa przy użyciu odwrotnego proxy, takiego jak nginx, lighttpd lub w varnish. Większość optymalizacji http, takich jak gzipowanie, może być korzystna na poziomie aplikacji, dzięki czemu można mieć bardzo szczegółowe podejście do tego, jakie zasoby mają być wykonywane przy użyciu programu gzip.

Właściwie stworzyłem własny moduł gzip dla expressjs / connect o nazwie gzippo https://github.com/tomgco/gzippo, chociaż nowy spełnia swoje zadanie. Dodatkowo używa kompresji węzła zamiast odradzania polecenia unix gzip.

tomgco
źródło
3
Używam gzippo na małym serwerze WWW node.js, dobra rzecz!
bosgood
1
jak sprawdzić, czy gzip jest stosowany do testów statycznych?
Rizwan Patel
5

Nawet jeśli nie używasz ekspresu, nadal możesz używać ich oprogramowania pośredniego. Moduł kompresji , co używam:

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
źródło
3

Podczas gdy inni słusznie zauważyli, używając front- endowego serwera WWW, który nginxmoże sobie z tym poradzić niejawnie, inną opcją jest użycie doskonałego node-http-proxy firmy nodejitsu do obsługi twoich zasobów.

na przykład:

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

Ten przykład pokazuje, wsparcie dla kompresji gzip dzięki zastosowaniu connect middleware modułu: connect-gzip.

kawalkada
źródło
3

Do skompresowania pliku możesz użyć poniższego kodu

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

Do rozpakowania tego samego pliku możesz użyć poniższego kodu

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
źródło
Chciałbym zobaczyć tekst opisu w tej odpowiedzi! Chociaż fragmenty kodu mogą odpowiedzieć na to pytanie, dobrą praktyką jest dołączenie kilku wyjaśnień dla TO i reszty świata, aby zrozumieć, dlaczego odpowiada na pytanie.
Clijsters
2

A co powiesz na to ?

node-compress
Moduł kompresji strumieniowej / gzip dla node.js
Aby zainstalować, upewnij się, że masz zainstalowaną bibliotekę libz i uruchom:
node-waf configure
node-waf build
Spowoduje to ustawienie modułu binarnego compress.node na build / default.
...

Shay Erlichmen
źródło
2

Istnieje wiele programów pośredniczących Gzip dla Express, KOA i innych. Na przykład: https://www.npmjs.com/package/express-static-gzip

Jednak Node bardzo źle radzi sobie z wykonywaniem zadań intensywnie wykorzystujących procesor, takich jak gzipping, kończenie SSL itp. Zamiast tego użyj „prawdziwych” usług oprogramowania pośredniego, takich jak nginx lub HAproxy, zobacz punkt 3 tutaj: http://goldbergyoni.com/checklist-best- praktyka-node-js-in-production /

Yonatan
źródło
2

Na dzień dzisiejszy epxress.compress()wydaje się, że wykonuje to świetną robotę.

W dowolnej aplikacji ekspresowej po prostu zadzwoń this.use(express.compress());.

Osobiście prowadzę lokomotywę na ekspresie i to działa pięknie. Nie mogę rozmawiać z żadnymi innymi bibliotekami lub frameworkami zbudowanymi na bazie Express, ale dopóki przestrzegają pełnej przejrzystości stosu, powinno być w porządku.

Crispen Smith
źródło
2
To naprawdę nie ma żadnych nowych informacji, powiela tę odpowiedź: stackoverflow.com/a/14341423/1355166
gcochard
1

Minęło kilka dobrych dni z node i masz rację, mówiąc, że nie możesz stworzyć serwera WWW bez programu gzip.

Na stronie modułów na Wiki Node.js podano wiele opcji. Wypróbowałem większość z nich, ale to jest ten, którego w końcu używam -

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

Wersja 1.0 również została wydana i do tej pory była dość stabilna.

Sudhanshu
źródło
Myślę, że twój komentarz jest nieco mylący. Chociaż gzip jest powszechny w nowoczesnych aplikacjach internetowych, nie jest konieczny . Myślę, że nieużywanie go jest całkowicie w porządku i zgodne ze standardami.
Simon East
1

Użyj kompresji gzip

Kompresja Gzip może znacznie zmniejszyć rozmiar treści odpowiedzi, a tym samym zwiększyć szybkość aplikacji internetowej. Użyj oprogramowania pośredniczącego do kompresji gzip w aplikacji Express. Na przykład:

var compression = require('compression');
var express = require('express')
var app = express()
app.use(compression())
Jai dewani
źródło
Czy musimy dekompresować rozmiar odpowiedzi do rozmiaru klienta?
Siddharth Sunchu