Node.js: Nén Gzip?


90

Tôi có sai khi nhận thấy rằng Node.js không nén gzip và không có mô-đun nào ngoài đó để thực hiện nén gzip? Làm thế nào mọi người có thể sử dụng một máy chủ web không có nén? Tôi còn thiếu gì ở đây? Tôi có nên thử — thở hổn hển — chuyển thuật toán sang JavaScript để sử dụng phía máy chủ không?

Câu trả lời:


74

Node v0.6.x hiện có một mô-đun zlib ổn định trong lõi - có một số ví dụ về cách sử dụng nó ở phía máy chủ trong tài liệu.

Một ví dụ (lấy từ tài liệu):

// 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
Tôi đã gặp sự cố với Internet Explorer không thích tiêu đề zlib mà tôi đã giải quyết bằng cách sử dụng 'createDeflateRaw' thay vì 'createDeflate'
đánh dấu

60

Nếu bạn đang sử dụng Express , thì bạn có thể sử dụng phương pháp nén của nó như một phần của cấu hình:

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

Và bạn có thể tìm thêm về nén ở đây: http://expressjs.com/api.html#compress

Và nếu bạn không sử dụng Express ... Tại sao không, anh bạn ?! :)

LƯU Ý: (cảm ơn @ankitjaininfo) Phần mềm trung gian này nên là một trong những phần mềm đầu tiên bạn "sử dụng" để đảm bảo tất cả các phản hồi được nén. Đảm bảo rằng điều này nằm trên các tuyến đường của bạn và trình xử lý tĩnh (ví dụ: cách tôi có nó ở trên).

LƯU Ý: (cảm ơn @ ciro-costa) Kể từ express 4.0, express.compressphần mềm trung gian không được dùng nữa. Nó được kế thừa từ kết nối 3.0 và express không còn bao gồm kết nối 3.0. Kiểm tra Express Compression để nhận phần mềm trung gian.


3
Bỏ phiếu xuống mà không có bình luận? Hãy cho tôi biết tại sao và hy vọng tôi có thể cải thiện câu trả lời. Hoặc thoải mái chỉnh sửa cho mình.
Milimetric

2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Đảm bảo rằng điều này nằm trên các tuyến đường của bạn và trình xử lý tĩnh
ankitjaininfo

14
Từ bây giờ express.compressphần mềm trung gian (được kế thừa từ kết nối 3.0 <) không được dùng nữa (kể từ express 4.0) vì nó không bao gồm kết nối 3.0 <nữa. Kiểm tra github.com/expressjs/compression để nhận phần mềm trung gian.
Ciro Costa

2
thành "Tại sao không, anh bạn ?!", các biểu đồ trên trang này so sánh http thô và khung express có thể cho bạn lý do. nhanh chậm nó xuống một chút raygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis

:) Điều đó có nghĩa là một chút lưỡi vào má. Tôi thực sự không thích thể hiện, có nhiều điều tôi ước nó đã làm và đánh bóng nhiều hơn nữa tôi ước nó có. Nhưng tôi cho rằng nó hoạt động đủ tốt, cho đến khi có thứ khác làm lu mờ nó.
Milimetric

43

1- Cài đặt nén

npm install compression

2- Sử dụng nó

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

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

nén trên Github


1
làm thế nào để kiểm tra xem thử nghiệm tĩnh có phải là gzip hay không!
Rizwan Patel

hình ảnh của tôi không nhận được gzip
Jeson Dias

thực sự bạn nên phần mềm trung gian này khi bạn đang gửi các tệp JS / CSS lớn hoặc các tệp JSON lớn .. sử dụng phần mềm trung gian này sẽ không mang lại lợi ích cho bạn, thay vào đó nó sẽ tiêu tốn nhiều tài nguyên cpu hơn. @JesonDias
Shyam

@JesonDias bạn không nên gzip hình ảnh vì JPEG đã bao gồm một thuật ngữ nén hoạt động tốt hơn nhiều cho hình ảnh so với gzip. gzip là nhiều hơn cho nội dung dựa trên văn bản.
user3413723

33

Nói chung, đối với một ứng dụng web sản xuất, bạn sẽ muốn đặt ứng dụng node.js của mình đằng sau một proxy ngược nhẹ như nginx hoặc lighttpd. Trong số nhiều lợi ích của thiết lập này, bạn có thể định cấu hình proxy ngược để thực hiện nén http hoặc thậm chí nén tls mà không cần phải thay đổi mã nguồn ứng dụng của mình.


không để nút phân phát các tệp tĩnh, hãy để proxy đảm nhiệm việc nén, thấy đó là phương pháp hay nhất trong prod-env, bạn có thể muốn sử dụng nginx hoặc lighty dù sao để tránh nút root usr đang chạy trên cổng 80
ezmilhouse

Tùy thuộc vào cách sử dụng, tôi thực sự coi đây là câu trả lời đúng.
prasanthv

@ezmilhouse Ngay cả khi bạn có proxy, máy chủ node.js của bạn vẫn phải cung cấp các tệp tĩnh đó cho proxy và không có lý do gì để lãng phí băng thông ngay cả trong các đường ống bên trong cùng một máy.
BT

8

Mặc dù bạn có thể gzip bằng cách sử dụng proxy ngược như nginx, lighttpd hoặc trong véc ni. Có thể có lợi khi có hầu hết các tối ưu hóa http, chẳng hạn như gzipping ở cấp ứng dụng để bạn có thể có cách tiếp cận chi tiết hơn về nội dung cần gzip.

Tôi đã thực sự tạo mô-đun gzip của riêng mình cho expressjs / connect có tên là gzippo https://github.com/tomgco/gzippo mặc dù nó mới thực hiện công việc. Thêm vào đó, nó sử dụng tính năng nén nút thay vì tạo ra lệnh gzip unix.


3
Tôi đang sử dụng gzippo trên một máy chủ web node.js nhỏ ngay bây giờ, rất hay!
bosgood

1
làm thế nào để kiểm tra xem gzip có được áp dụng cho các thử nghiệm tĩnh không?
Rizwan Patel

4

Ngay cả khi bạn không sử dụng express, bạn vẫn có thể sử dụng phần mềm trung gian của họ. Các mô-đun nén là những gì tôi đang sử dụng:

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

Trong khi những người khác đã chỉ ra rằng sử dụng một máy chủ web giao diện người dùng nginxcó thể xử lý ngầm này, một tùy chọn khác là sử dụng node-http-proxy tuyệt vời của nodejitsu để cung cấp nội dung của bạn.

ví dụ:

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

Ví dụ này chứng tỏ sự ủng hộ cho việc nén gzip thông qua việc sử dụng các trung gian kết nối mô-đun: connect-gzip.


3

Để nén tệp, bạn có thể sử dụng mã dưới đây

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

Để giải nén cùng một tệp, bạn có thể sử dụng mã dưới đây

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

Rất thích xem một số văn bản mô tả trong câu trả lời này! Mặc dù các đoạn mã của bạn có thể trả lời câu hỏi, nhưng bạn nên đưa vào một số giải thích cho TO và phần còn lại của thế giới để hiểu tại sao nó trả lời câu hỏi.
Clijsters

2

Làm thế nào về điều này ?

nút-nén
Một mô-đun nén / gzip phát trực tuyến cho node.js
Để cài đặt, hãy đảm bảo rằng bạn đã cài đặt libz và chạy:
node-waf config
node-waf build
Điều này sẽ đặt mô-đun nhị phân nén.node trong build / default.
...


2

Có nhiều phần mềm trung gian Gzip cho Express, KOA và những phần mềm khác. Ví dụ: https://www.npmjs.com/package/express-static-gzip

Tuy nhiên, Node rất tệ khi thực hiện các tác vụ chuyên sâu của CPU như gzipping, kết thúc SSL, v.v. Thay vào đó, hãy sử dụng các dịch vụ phần mềm trung gian 'thực sự' như nginx hoặc HAproxy, xem đạn 3 tại đây: http://goldbergyoni.com/checklist-best- Practice-of-node-js-in-production /


2

Cho đến ngày hôm nay, epxress.compress()dường như đang làm một công việc xuất sắc của điều này.

Trong bất kỳ ứng dụng nhanh nào chỉ cần gọi this.use(express.compress());.

Cá nhân tôi đang chạy xe cào cào và điều này đang hoạt động rất tốt. Tôi không thể nói chuyện với bất kỳ thư viện hoặc khuôn khổ nào khác được xây dựng trên express nhưng miễn là chúng tôn trọng tính minh bạch của toàn bộ ngăn xếp thì bạn sẽ ổn.


2
Điều này không thực sự có bất kỳ thông tin mới, nó trùng lặp câu trả lời này: stackoverflow.com/a/14341423/1355166
gcochard

1

Đã một vài ngày tốt lành với node và bạn đúng khi nói rằng bạn không thể tạo máy chủ web mà không có gzip.

Có khá nhiều tùy chọn được đưa ra trên trang mô-đun trên Wiki Node.js. Tôi đã thử hầu hết trong số chúng, nhưng đây là cái cuối cùng tôi đang sử dụng -

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

v1.0 cũng đã ra mắt và nó hoạt động khá ổn định cho đến nay.


Tôi nghĩ rằng bình luận của bạn là một chút sai lầm. Mặc dù gzip phổ biến trong các ứng dụng web hiện đại, nhưng nó không phải là điều cần thiết . Tôi nghĩ rằng nó hoàn toàn tốt và tuân thủ các tiêu chuẩn để không sử dụng nó.
Simon East

1

Sử dụng nén gzip

Nén Gzip có thể làm giảm đáng kể kích thước của phần thân phản hồi và do đó làm tăng tốc độ của ứng dụng web. Sử dụng phần mềm trung gian nén để nén gzip trong ứng dụng Express của bạn. Ví dụ:

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

Chúng ta có cần giải nén kích thước phản hồi ở kích thước máy khách không?
Siddharth Sunchu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.