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


91

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


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


1
как проверить, является ли статическая сборка gzip или нет!
— Ризван Патель

мои изображения не архивируются
— 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 или в varnish. Может быть полезно иметь большую часть оптимизаций http, таких как gzip на уровне приложения, чтобы вы могли иметь более детальный подход к тому, какие ресурсы gzip.

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


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)

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 широко используется в современных веб-приложениях, в нем нет необходимости . Я думаю, что это нормально и соответствует стандартам не использовать его.
— Саймон Ист
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.