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.