Node.js: การบีบอัด Gzip?


91

ฉันผิดหรือไม่ที่พบว่า Node.js ไม่มีการบีบอัด gzip และไม่มีโมดูลใดที่จะทำการบีบอัด gzip ทุกคนจะใช้เว็บเซิร์ฟเวอร์ที่ไม่มีการบีบอัดได้อย่างไร? ฉันขาดอะไรไปที่นี่? ฉันควรลอง - อ้าปากค้าง - พอร์ตอัลกอริทึมเป็น JavaScript สำหรับการใช้งานฝั่งเซิร์ฟเวอร์หรือไม่

คำตอบ:


74

โหนด v0.6.x มีโมดูล zlib ที่เสถียรในแกนแล้วตอนนี้มีตัวอย่างบางส่วนเกี่ยวกับวิธีการใช้งานฝั่งเซิร์ฟเวอร์ในเอกสารด้วย

ตัวอย่าง (นำมาจากเอกสาร):

// 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
ฉันพบปัญหากับ Internet Explorer ที่ไม่ชอบส่วนหัว zlib ซึ่งฉันแก้ไขโดยใช้ 'createDeflateRaw' แทน 'createDeflate'
ทำเครื่องหมาย

60

หากคุณใช้Expressคุณสามารถใช้วิธีการบีบอัดเป็นส่วนหนึ่งของการกำหนดค่า:

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

และคุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับการบีบอัดได้ที่นี่: http://expressjs.com/api.html#compress

และถ้าคุณไม่ได้ใช้Express ... ทำไมไม่ล่ะ! :)

หมายเหตุ: (ขอบคุณ @ankitjaininfo) มิดเดิลแวร์นี้ควรเป็นหนึ่งในตัวแรกที่คุณ "ใช้" เพื่อให้แน่ใจว่าการตอบกลับทั้งหมดถูกบีบอัด ตรวจสอบให้แน่ใจว่าสิ่งนี้อยู่เหนือเส้นทางและตัวจัดการแบบคงที่ของคุณ (เช่นฉันมีวิธีการด้านบนอย่างไร)

หมายเหตุ: (ขอบคุณ @ ciro-costa) ตั้งแต่ express 4.0 express.compressมิดเดิลแวร์จึงเลิกใช้งาน ได้รับการสืบทอดมาจากการเชื่อมต่อ 3.0 และ Express ไม่รวมการเชื่อมต่อ 3.0 อีกต่อไป ตรวจสอบการบีบอัดด่วนเพื่อรับมิดเดิลแวร์


3
ลงคะแนนโดยไม่แสดงความคิดเห็น? แจ้งให้เราทราบสาเหตุและหวังว่าจะสามารถปรับปรุงคำตอบได้ หรือแก้ไขเองได้ตามสบาย
Milimetric

2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. ตรวจสอบให้แน่ใจว่าสิ่งนี้อยู่เหนือเส้นทางและตัวจัดการแบบคงที่ของคุณ
ankitjaininfo

14
จากนี้ไปexpress.compressมิดเดิลแวร์ (ซึ่งสืบทอดมาจากการเชื่อมต่อ 3.0 <) จะเลิกใช้งาน (ตั้งแต่ express 4.0) เนื่องจากไม่มีการเชื่อมต่อ 3.0 <อีกต่อไป ตรวจสอบgithub.com/expressjs/compressionเพื่อรับมิดเดิลแวร์
Ciro Costa

2
ถึง "ทำไมไม่ล่ะ!" กราฟในหน้านี้เปรียบเทียบ http ดิบและเฟรมเวิร์กด่วนอาจให้เหตุผลแก่คุณ express ทำให้ช้าลงหน่อยraygun.io/blog/2015/02/node-js-performance-node-js-vs-io-js
ejfrancis

:) นั่นหมายถึงการเอาลิ้นดุนแก้ม จริงๆแล้วฉันไม่ได้รักการแสดงออกมีหลายสิ่งหลายอย่างที่ฉันหวังว่ามันจะเป็นเช่นนั้นและฉันหวังว่ามันจะขัดเกลาอีกมากมาย แต่มันก็ทำได้ดีพอที่ฉันคิดว่าจนกว่าสิ่งอื่นจะบดบังมัน
Milimetric

43

1- ติดตั้งการบีบอัด

npm install compression

2- ใช้มัน

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

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

การบีบอัดบน Github


1
วิธีตรวจสอบว่า static assest เป็น gzip หรือไม่!
Rizwan Patel

ภาพของฉันไม่ได้รับการบีบอัด
Jeson Dias

ที่จริงคุณควรเป็นมิดเดิลแวร์นี้เมื่อคุณส่งไฟล์ JS / CSS ขนาดใหญ่หรือไฟล์ JSON ขนาดใหญ่ .. การใช้มิดเดิลแวร์นี้จะไม่ให้ประโยชน์กับคุณ แต่จะใช้ทรัพยากร cpu มากกว่า @JesonDias
Shyam

@JesonDias คุณไม่ควร gzip ภาพเพราะ JPEG มี algo การบีบอัดอยู่แล้วซึ่งทำงานได้ดีกว่า gzip มาก gzip เป็นมากกว่าสำหรับสิ่งที่เป็นข้อความ
user3413723

33

โดยทั่วไปสำหรับเว็บแอปพลิเคชันที่ใช้งานจริงคุณจะต้องวางแอป node.js ไว้ด้านหลังพร็อกซีย้อนกลับที่มีน้ำหนักเบาเช่น nginx หรือ lighttpd ในข้อดีมากมายของการตั้งค่านี้คุณสามารถกำหนดค่า reverse proxy เพื่อทำการบีบอัด http หรือแม้กระทั่งการบีบอัด tls โดยไม่ต้องเปลี่ยนซอร์สโค้ดแอปพลิเคชัน


อย่าปล่อยให้โหนดให้บริการไฟล์คงที่ปล่อยให้พร็อกซีดูแลการบีบอัดพบว่าเป็นแนวทางปฏิบัติที่ดีที่สุดใน prod-env คุณอาจต้องการใช้ nginx หรือ lighty ต่อไปเพื่อหลีกเลี่ยงการรูท usr ที่รันโหนดบนพอร์ต 80
ezmilhouse

ขึ้นอยู่กับการใช้งานฉันคิดว่านี่เป็นคำตอบที่ถูกต้อง
prasanthv

@ezmilhouse แม้ว่าคุณจะมีพร็อกซี แต่เซิร์ฟเวอร์ node.js ของคุณก็ยังต้องให้บริการไฟล์คงที่เหล่านั้นไปยังพร็อกซีและไม่มีเหตุผลที่จะเสียแบนด์วิดท์แม้จะอยู่ในไพพ์ภายในเครื่องเดียวกันก็ตาม
BT

8

แม้ว่าคุณจะสามารถ gzip โดยใช้ reverse proxy เช่น nginx, lighttpd หรือในวานิช การเพิ่มประสิทธิภาพ http ส่วนใหญ่จะเป็นประโยชน์เช่นการ gzipping ที่ระดับแอปพลิเคชันเพื่อให้คุณมีแนวทางที่ละเอียดยิ่งขึ้นเกี่ยวกับเนื้อหาที่จะ gzip

ฉันได้สร้างโมดูล gzip ของตัวเองสำหรับ expressjs / connect ที่เรียกว่า gzippo https://github.com/tomgco/gzippoแม้ว่ามันจะใหม่ก็ตาม นอกจากนี้ยังใช้การบีบอัดโหนดแทนการวางไข่คำสั่ง unix gzip


3
ตอนนี้ฉันใช้ gzippo บนเว็บเซิร์ฟเวอร์ node.js ขนาดเล็กสิ่งดีๆ!
bosgood

1
วิธีตรวจสอบว่า gzip ใช้กับการทดสอบแบบคงที่หรือไม่
Rizwan Patel

5

แม้ว่าคุณจะไม่ได้ใช้ Express แต่คุณก็ยังใช้มิดเดิลแวร์ได้ โมดูลการบีบอัดคือสิ่งที่ฉันใช้:

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

ในขณะที่คนอื่น ๆ ได้ชี้ให้เห็นอย่างถูกต้องโดยใช้เว็บเซิร์ฟเวอร์ส่วนหน้าเช่นnginxสามารถจัดการสิ่งนี้ได้โดยปริยาย แต่อีกทางเลือกหนึ่งคือการใช้node-http-proxy ที่ยอดเยี่ยมของ nodejitsuเพื่อให้บริการสินทรัพย์

เช่น:

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

ตัวอย่างนี้แสดงให้เห็นถึงการสนับสนุนสำหรับการบีบอัด gzip ผ่านการใช้ตัวกลางเชื่อมต่อconnect-gzipโมดูล:


3

สำหรับการบีบอัดไฟล์คุณสามารถใช้โค้ดด้านล่าง

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

สำหรับการขยายไฟล์เดียวกันคุณสามารถใช้รหัสด้านล่าง

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

ชอบที่จะเห็นข้อความอธิบายในคำตอบนี้! แม้ว่าข้อมูลโค้ดของคุณอาจตอบคำถามได้ แต่ก็ควรรวมคำอธิบายบางส่วนสำหรับ TO และส่วนอื่น ๆ ของโลกเพื่อทำความเข้าใจว่าเหตุใดจึงตอบคำถามได้
Clijsters

2

แล้วเรื่องนี้ล่ะ?

node-compress
โมดูลการบีบอัดแบบสตรีมมิ่ง / gzip สำหรับ node.js
ในการติดตั้งตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง libz แล้วและรัน:
node-waf กำหนดค่า
node-waf build
ซึ่งจะทำให้โมดูลไบนารี compress.node ใน build / default
...


2

มีตัวกลาง Gzip หลายรายการสำหรับ Express, KOA และอื่น ๆ ตัวอย่างเช่น: https://www.npmjs.com/package/express-static-gzip

อย่างไรก็ตาม Node แย่มากในการทำงานที่ต้องใช้ CPU มากเช่น gzipping, การยกเลิก SSL ฯลฯ ให้ใช้บริการมิดเดิลแวร์ 'ของจริง' เช่น nginx หรือ HAproxy ดูหัวข้อย่อย 3 ที่นี่: http://goldbergyoni.com/checklist-best- การปฏิบัติของโหนด js ในการผลิต /


2

ใช้การบีบอัด gzip

การบีบอัด Gzip สามารถลดขนาดของเนื้อหาตอบสนองได้มากและด้วยเหตุนี้จึงเพิ่มความเร็วของเว็บแอป ใช้มิดเดิลแวร์การบีบอัดสำหรับการบีบอัด gzip ในแอป Express ของคุณ ตัวอย่างเช่น:

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

เราจำเป็นต้องขยายขนาดการตอบสนองที่ขนาดไคลเอนต์หรือไม่?
Siddharth Sunchu

2

ณ วันนี้, epxress.compress()ดูเหมือนว่าจะทำงานได้อย่างยอดเยี่ยมในเรื่องนี้

ในแอพด่วนใด ๆ เพียงโทร this.use(express.compress());ด่วนเพียงโทร

ฉันใช้หัวรถจักรอยู่บนรถด่วนเป็นการส่วนตัวและมันก็ทำงานได้ดี ฉันไม่สามารถพูดคุยกับไลบรารีหรือเฟรมเวิร์กอื่น ๆ ที่สร้างขึ้นบน Express ได้ แต่ตราบใดที่พวกเขาให้เกียรติความโปร่งใสแบบเต็มสแต็กคุณควรจะสบายดี


2
นี่ไม่มีข้อมูลใหม่จริงๆคำตอบนี้ซ้ำกัน: stackoverflow.com/a/14341423/1355166
gcochard

1

เป็นเวลาสองสามวันที่ดีกับ node และคุณพูดถูกว่าคุณไม่สามารถสร้างเว็บเซิร์ฟเวอร์ได้หากไม่มี gzip

มีตัวเลือกมากมายที่ให้ไว้ในหน้าโมดูลบน Node.js Wiki ฉันลองใช้เกือบทั้งหมดแล้ว แต่นี่เป็นสิ่งที่ฉันใช้ในที่สุด -

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

v1.0 ก็ออกมาแล้วและมันก็ค่อนข้างเสถียรแล้ว


ฉันคิดว่าความคิดเห็นของคุณอาจทำให้เข้าใจผิดได้เล็กน้อย ในขณะที่ gzip เป็นเรื่องธรรมดาในการใช้งานเว็บสมัยใหม่ก็ไม่ได้เป็นความจำเป็น ฉันคิดว่ามันสมบูรณ์ดีและเป็นไปตามมาตรฐานที่จะไม่ใช้มัน
Simon East
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.