Node.js: Kompresi Gzip?

90

Apakah saya salah menemukan bahwa Node.js tidak melakukan kompresi gzip dan tidak ada modul di luar sana untuk melakukan kompresi gzip? Bagaimana orang bisa menggunakan server web yang tidak memiliki kompresi? Apa yang kulewatkan di sini? Haruskah saya mencoba — terkesiap — mentransfer algoritme ke JavaScript untuk penggunaan di sisi server?

SnickersAreMyFave
sumber

Jawaban:

74

Node v0.6.x memiliki modul zlib yang stabil di intinya - ada beberapa contoh tentang cara menggunakannya di sisi server di dokumen juga.

Contoh (diambil dari dokumen):

// 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
sumber
1
Saya mengalami masalah dengan Internet Explorer yang tidak menyukai tajuk zlib yang saya selesaikan dengan menggunakan 'createDeflateRaw' daripada 'createDeflate'
tandai
60

Jika Anda menggunakan Express , Anda dapat menggunakan metode kompresnya sebagai bagian dari konfigurasi:

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

Dan Anda dapat menemukan lebih banyak tentang kompres di sini: http://expressjs.com/api.html#compress

Dan jika Anda tidak menggunakan Express ... Mengapa tidak, bung ?! :)

CATATAN: (terima kasih kepada @ankitjaininfo) Middleware ini harus menjadi salah satu yang pertama Anda "gunakan" untuk memastikan semua tanggapan dikompresi. Pastikan ini di atas rute dan pengendali statis Anda (mis. Bagaimana saya memilikinya di atas).

CATATAN: (terima kasih kepada @ ciro-costa) Sejak express 4.0, express.compressmiddleware tidak digunakan lagi. Itu diwarisi dari connect 3.0 dan express tidak lagi menyertakan connect 3.0. Periksa Kompresi Ekspres untuk mendapatkan middleware.

Milimetrik
sumber
3
Tidak suka tanpa komentar? Beri tahu saya alasannya dan semoga saya dapat meningkatkan jawabannya. Atau silakan edit sendiri.
Milimetri
2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Pastikan bahwa ini di atas rute dan pengendali statis Anda
ankitjaininfo
14
Mulai sekarang express.compressmiddleware (yang diwarisi dari connect 3.0 <) tidak digunakan lagi (sejak express 4.0) karena tidak lagi menyertakan connect 3.0 <. Periksa github.com/expressjs/compression untuk mendapatkan middleware.
Ciro Costa
2
hingga "Mengapa tidak, kawan ?!", grafik di halaman ini yang membandingkan http mentah dan kerangka kerja ekspres dapat memberi Anda alasan. express memperlambatnya sedikit raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis
:) Itu dimaksudkan untuk menjadi sedikit lidah. Saya sebenarnya tidak suka berekspresi, ada banyak hal yang saya harapkan dan lebih banyak polesan yang saya harapkan. Tapi itu cukup baik saya kira, sampai sesuatu yang lain mengalahkannya.
Milimetri
43

1- Instal kompresi

npm install compression

2- Gunakan itu

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

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

kompresi di Github

CoyBit
sumber
1
bagaimana cara memeriksa apakah assest statis adalah gzip atau tidak!
Rizwan Patel
gambar saya tidak di-gzip
Jeson Dias
sebenarnya Anda harus menggunakan middleware ini ketika Anda mengirim file JS / CSS yang besar atau file JSON yang besar .. menggunakan middleware ini tidak akan memberi Anda keuntungan, melainkan akan menghabiskan lebih banyak sumber daya cpu. @JesonDias
Shyam
@JesonDias Anda tidak boleh meng-gzip gambar karena JPEG sudah menyertakan algo kompresi yang bekerja jauh lebih baik untuk gambar daripada gzip. gzip lebih untuk hal-hal berbasis teks.
pengguna3413723
33

Secara umum, untuk aplikasi web produksi, Anda akan ingin meletakkan aplikasi node.js Anda di belakang proxy terbalik ringan seperti nginx atau lighttpd. Di antara banyak keuntungan dari setup ini, Anda dapat mengkonfigurasi reverse proxy untuk melakukan kompresi http atau bahkan kompresi tls, tanpa harus mengubah kode sumber aplikasi Anda.

yfeldblum
sumber
jangan biarkan node melayani file statis, biarkan proxy menangani kompresi, anggap itu sebagai praktik terbaik di prod-env, Anda mungkin ingin menggunakan nginx atau ringan untuk menghindari root usr Anda menjalankan node pada port 80
ezmilhouse
Bergantung pada penggunaannya, saya benar-benar menganggap ini sebagai jawaban yang benar.
prasanthv
@ezmilhouse Meskipun Anda memiliki proxy, server node.js Anda masih harus menyajikan file statis tersebut ke proxy, dan tidak ada alasan untuk membuang bandwidth bahkan dalam pipa di dalam mesin yang sama.
BT
8

Meskipun Anda dapat melakukan gzip menggunakan proxy terbalik seperti nginx, lighttpd, atau pernis. Memiliki sebagian besar pengoptimalan http seperti melakukan gzip pada tingkat aplikasi dapat bermanfaat sehingga Anda dapat memiliki pendekatan yang lebih terperinci tentang aset apa yang akan di-gzip.

Saya sebenarnya telah membuat modul gzip saya sendiri untuk expressjs / connect yang disebut gzippo https://github.com/tomgco/gzippo meskipun baru itu melakukan pekerjaan itu. Selain itu, ia menggunakan kompres node daripada menjalankan perintah unix gzip.

tomgco
sumber
3
Saya menggunakan gzippo pada server web node.js kecil sekarang, bagus!
bosgood
1
bagaimana cara memeriksa apakah gzip diterapkan pada assest statis?
Rizwan Patel
5

Meskipun Anda tidak menggunakan express, Anda masih dapat menggunakan middleware mereka. The modul kompresi adalah apa yang saya gunakan:

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
sumber
3

Sementara seperti yang orang lain tunjukkan menggunakan server web ujung depan seperti nginxdapat menangani ini secara implisit, opsi lain, adalah menggunakan node-http-proxy yang sangat baik dari nodejitsu untuk melayani aset Anda.

misalnya:

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

Contoh ini menunjukkan dukungan untuk kompresi gzip melalui penggunaan middleware koneksi modul: connect-gzip.

pawai
sumber
3

Untuk mengompresi file Anda dapat menggunakan kode di bawah ini

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

Untuk mendekompresi file yang sama Anda dapat menggunakan kode di bawah ini

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
sumber
Akan sangat senang melihat beberapa teks deskripsi dalam jawaban ini! Meskipun cuplikan kode Anda mungkin menjawab pertanyaan tersebut, praktik yang baik adalah menyertakan beberapa penjelasan untuk TO dan seluruh dunia untuk memahami mengapa ia menjawab pertanyaan tersebut.
Clijsters
2

Bagaimana kalau begini ?

node-compress
Modul kompresi / gzip streaming untuk node.js
Untuk menginstal, pastikan bahwa Anda telah menginstal libz, dan jalankan:
node-waf configure
node-waf build
Ini akan menempatkan modul biner compress.node dalam build / default.
...

Shay Erlichmen
sumber
2

Mulai hari ini, epxress.compress() tampaknya melakukan pekerjaan yang brilian ini.

Di aplikasi ekspres apa pun, panggil saja this.use(express.compress()); .

Saya menjalankan lokomotif di atas kereta ekspres secara pribadi dan ini bekerja dengan baik. Saya tidak dapat berbicara dengan pustaka atau kerangka kerja lain yang dibangun di atas express tetapi selama mereka menghormati transparansi tumpukan penuh, Anda akan baik-baik saja.

Crispen Smith
sumber
2
Ini tidak benar-benar memiliki informasi baru, ini menduplikasi jawaban ini: stackoverflow.com/a/14341423/1355166
gcochard
1

Sudah beberapa hari yang baik dengan node, dan Anda benar untuk mengatakan bahwa Anda tidak dapat membuat server web tanpa gzip.

Ada cukup banyak opsi yang diberikan pada halaman modul di Wiki Node.js. Saya mencoba sebagian besar, tetapi ini yang akhirnya saya gunakan -

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

v1.0 juga keluar dan sejauh ini cukup stabil.

Sudhanshu
sumber
Saya pikir komentar Anda agak menyesatkan. Meskipun gzip umum digunakan dalam aplikasi web modern, ini bukanlah suatu keharusan . Saya pikir itu baik-baik saja dan sesuai standar untuk tidak menggunakannya.
Simon East
1

Gunakan kompresi gzip

Pengompresan Gzip dapat sangat mengurangi ukuran tubuh respons dan karenanya meningkatkan kecepatan aplikasi web. Gunakan middleware kompresi untuk kompresi gzip di aplikasi Express Anda. Sebagai contoh:

var compression = require('compression');
var express = require('express')
var app = express()
app.use(compression())
Jai dewani
sumber
Apakah kita perlu mendekompresi ukuran respons pada ukuran klien?
Siddharth Sunchu