Node.js: Стиснення Gzip?


90

Я помиляюся, виявивши, що Node.js не виконує стиснення gzip і не існує модулів для стиснення gzip? Як хтось може використовувати веб-сервер, який не стискає? Чого мені тут не вистачає? Чи слід намагатися "задихатись" перенести алгоритм на JavaScript для використання на сервері?

Відповіді:


74

Node 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проміжне програмне забезпечення застаріло. Він успадкований від connect 3.0 і express більше не включає connect 3.0. Перевірте Express Compression для отримання проміжного програмного забезпечення.


3
Голосувати проти без коментаря? Повідомте мене, чому, і, сподіваюся, я можу покращити відповідь. Або сміливо редагуйте самі.
Milimetric

2
This middleware should be placed "high" within the stack to ensure all responses may be compressed. Переконайтеся, що це вище ваших маршрутів та статичного обробника
ankitjaininfo

14
Відтепер express.compressпроміжне програмне забезпечення (яке успадкувало від connect 3.0 <) застаріло (оскільки Express 4.0), оскільки воно більше не включає connect 3.0 <. Перевірте github.com/expressjs/compression для отримання проміжного програмного забезпечення.
Ciro Costa

2
до "Чому ні, чоловіче ?!", графіки на цій сторінці, що порівнюють необроблений http і express framework, можуть дати вам причину. 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 чи ні!
Різван Пател

мої зображення не отримують gzipped
Jeson Dias

насправді вам слід використовувати це проміжне програмне забезпечення, коли ви надсилаєте великі файли JS / CSS або великі файли JSON .. використання цього проміжного програмного забезпечення не принесе вам користі, натомість воно споживатиме більше ресурсів процесора. @JesonDias
Shyam

@JesonDias, ви не повинні створювати зображення у стилі gzip, оскільки JPEG вже включає алгоритм стиснення, який працює набагато краще для зображень, ніж gzip. gzip - це більше для текстових матеріалів.
user3413723

33

Взагалі кажучи, для робочої веб-програми ви хочете поставити свою програму node.js за полегшений зворотний проксі-сервер, такий як nginx або lighttpd. Серед багатьох переваг цього налаштування ви можете налаштувати зворотний проксі-сервер для стиснення http або навіть стиснення tls, не змінюючи вихідний код програми.


не дозволяйте вузлу обслуговувати статичні файли, нехай проксі піклується про стиснення, вважайте це найкращою практикою у prod-env, ви все одно можете використовувати nginx або lighty, щоб уникнути запуску вашого кореневого usr-вузла на порту 80
ezmilhouse

Залежно від використання, я справді вважаю, що це правильна відповідь.
prasanthv

@ezmilhouse Навіть якщо у вас є проксі-сервер, ваш сервер node.js все одно повинен подавати ці статичні файли проксі-серверу, і немає жодної причини витрачати пропускну здатність навіть у трубах всередині тієї ж машини.
BT

8

Хоча ви можете gzip використовувати, використовуючи зворотний проксі, такий як nginx, lighttpd або в лаку. Може бути корисно мати більшість оптимізацій http, таких як gzipping на рівні програми, щоб ви могли мати набагато детальніший підхід до того, які активи потрібно gzip.

Я насправді створив власний модуль gzip для expressjs / connect, який називається gzippo https://github.com/tomgco/gzippo, хоча новий він робить цю роботу. Крім того, він використовує стискання вузлів замість нересту команди unix gzip.


3
Зараз я використовую gzippo на невеликому веб-сервері node.js, хороші речі!
bosgood 01.03.12

1
як перевірити, чи застосовано gzip до статичних асестів?
Різван Патель

4

Навіть якщо ви не використовуєте 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можна впоратися з цим неявно, ще один варіант, щоб використовувати nodejitsu в відмінний вузол-HTTP-проксі , щоб обслуговувати свої активи.

наприклад:

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

Хотілося б побачити описовий текст у цій відповіді! Незважаючи на те, що фрагменти коду можуть відповісти на питання, корисно включити деякі пояснення для ТО та решти світу, щоб зрозуміти, чому він відповідає на питання.
Клайстерс

2

Як щодо цього ?

node-compress
Потокове стиснення / gzip-модуль для node.js
Для встановлення переконайтесь, що у вас встановлений libz, і запустіть:
node-waf configure
node-waf build
Це встановить двійковий модуль compress.node у build / default.
...


2

Існує кілька проміжних програм Gzip для Express, KOA та інших. Наприклад: https://www.npmjs.com/package/express-static-gzip

Однак Node жахливо виконує такі інтенсивні завдання, як gzipping, припинення SSL тощо. Натомість використовуйте "справжні" сервіси проміжного програмного забезпечення, такі як nginx або HAproxy, див. Маркер 3 тут: http://goldbergyoni.com/checklist-best- практика-вузла-js-у-виробництві /


2

На сьогодні, epxress.compress()схоже, це робить блискучу роботу.

У будь-якому експрес-додатку просто телефонуйте this.use(express.compress());.

Я особисто керую локомотивом поверх Express, і це працює чудово. Я не можу розмовляти з будь-якими іншими бібліотеками чи фреймворками, побудованими поверх express, але якщо вони дотримуються повної прозорості стека, ви повинні бути в порядку.


2
Це дійсно не має ніякої нової інформації, він дублює цю відповідь: stackoverflow.com/a/14341423/1355166
gcochard

1

Пройшло кілька хороших днів з node, і ви праві сказати, що не можете створити веб-сервер без gzip.

На сторінці модулів на Вікі Node.js є досить багато варіантів. Я випробував більшість з них, але саме цей я нарешті використовую -

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

v1.0 також вийшов, і дотепер він був досить стабільним.


Я думаю, що ваш коментар дещо вводить в оману. Хоча gzip поширений у сучасних веб-додатках, це не є необхідністю . Я вважаю, що це абсолютно нормально та не відповідає стандартам, якщо його не використовувати.
Simon East

1

Використовуйте стиснення gzip

Стиснення Gzip може значно зменшити розмір тіла відповіді і, отже, збільшити швидкість веб-програми. Використовуйте проміжне програмне забезпечення для стиснення для стиснення gzip у вашому додатку Express. Наприклад:

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

Чи потрібно нам розпаковувати розмір відповіді за розміром клієнта?
Сіддхарт Сунчу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.