Node.js: сжатие Gzip?

91

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

SnickersAreMyFave
источник

Ответы:

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. Проверьте экспресс-сжатие для получения промежуточного программного обеспечения.

Милиметрический
источник
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, чтобы получить промежуточное ПО.
Чиро Коста
2
на «Почему бы и нет, чувак ?!» графики на этой странице, сравнивающие необработанный http и экспресс-фреймворк, могут дать вам причину. экспресс немного замедляет его 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

CoyBit
источник
1
как проверить, является ли статическая сборка gzip или нет!
Ризван Патель
мои изображения не архивируются
Jeson Dias
на самом деле вам следует использовать это промежуточное программное обеспечение, когда вы отправляете большие файлы JS / CSS или большие файлы JSON ... использование этого промежуточного программного обеспечения не принесет вам пользы, вместо этого оно будет потреблять больше ресурсов процессора. @JesonDias
Shyam
@JesonDias, вам не следует сжимать изображения с помощью gzip, потому что JPEG уже включает алгоритм сжатия, который работает с изображениями намного лучше, чем gzip. gzip больше подходит для текстовых материалов.
user3413723
33

Вообще говоря, для производственного веб-приложения вам нужно разместить приложение node.js за легким обратным прокси-сервером, таким как nginx или lighttpd. Среди многих преимуществ этой настройки вы можете настроить обратный прокси-сервер для сжатия http или даже сжатия tls без необходимости изменять исходный код приложения.

Yfeldblum
источник
не позволяйте узлу обслуживать статические файлы, позвольте прокси-серверу позаботиться о сжатии, считайте, что это лучшая практика в prod-env, вы можете в любом случае использовать nginx или lighty, чтобы избежать запуска корневого узла usr на порту 80
ezmilhouse
В зависимости от использования, я действительно считаю это правильным ответом.
prasanthv
@ezmilhouse Даже если у вас есть прокси, ваш сервер node.js все равно должен обслуживать эти статические файлы на прокси, и нет причин тратить полосу пропускания даже в каналах внутри той же машины.
BT
8

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

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

Tomgco
источник
3
Сейчас я использую gzippo на небольшом веб-сервере node.js, хороший материал!
bosgood 01
1
как проверить, применяется ли gzip к статическим ассетам?
Rizwan Patel
5

Даже если вы не используете экспресс, вы все равно можете использовать их промежуточное ПО. Модуль сжатия является то , что я использую:

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
источник
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 и остального мира, чтобы понять, почему он отвечает на вопрос.
Клийстерс
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 ужасно плохо справляется с задачами с интенсивным использованием ЦП, такими как сжатие, завершение 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())
Джай Девани
источник
Нужно ли нам распаковывать размер ответа по размеру клиента?
Сиддхарт Сунчу
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 широко используется в современных веб-приложениях, в нем нет необходимости . Я думаю, что это нормально и соответствует стандартам не использовать его.
Саймон Ист