node.js HTTPサーバでレスポンスをgzipやdeflateで圧縮する
HTTPサーバ(ウェブサーバ)では、HTTPレスポンスを圧縮して、データ送信量を減らし、通信を速く終わらせることができます。node.jsのHTTPサーバ(ウェブサーバ)では、zlibを利用して、gzipやdeflateでHTTPレスポンスを圧縮できます
読み方
- zlib
- ぜっと りぶ
- gzip
- じーじっぷ
- deflate
- でふれいと
概要
HTTPサーバでレスポンスを圧縮することで、通信コストを下げることができます。データ量が小さくなれば、それだけ、データが速く、クライアントに到達します。サーバ側のOSとしては、速く、ネットワークのバッファをネットワークに送信できるので、OSリソースがその分、節約できます。
しかしながら、データを圧縮するには、CPUのコストを支払わなければなりません。負荷が上がってきたとき、必ずしもデータを圧縮するのが正しいとはいえない状況がでてくるかもしれません。また、圧縮に向かないデータもあるでしょう。たとえば、すでに圧縮されてしまっている画像データや音声データ(mp3)などです。
圧縮するべきか、よく考えて、レスポンスを操作するべきです。ある程度のサイズのテキストのデータであれば、圧縮の恩恵が受けやすいので基本的に圧縮してしまうのがよいでしょう。
ソースコード node http_zlib1.js
/* * http_zlib1.js * Copyright (C) 2014 kaoru <kaoru@bsd> */ var zlib = require('zlib'); var http = require('http'); var server = http.createServer(); server.on('request', doRequest); server.listen(8080); function doRequest(req, res) { var acceptEncoding = req.headers['accept-encoding']; if (! acceptEncoding ) { acceptEncoding = ''; } var output = 'Hello World\n'; var buf; console.log(acceptEncoding); if (acceptEncoding.match(/\bdeflate\b/)) { res.writeHead(200, {'Content-Type': 'text/plain', 'content-encoding': 'deflate'}); buf = new Buffer(output, 'utf-8'); zlib.deflate(buf, function(_, result){ //console.log(result); res.end(result); }); console.log('response is deflate'); } else if (acceptEncoding.match(/\bgzip\b/)) { res.writeHead(200, {'Content-Type': 'text/plain', 'content-encoding': 'gzip'}); buf = new Buffer(output, 'utf-8'); zlib.gzip(buf, function(_, result){ res.end(result); }); console.log('response is gzip'); } else { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(output); console.log('response is text'); } }
実行例
HTTPサーバを起動
node http_zlib1.js
使い方
curlコマンドでは、デフォルトでは、Accept-Encodingを指定しないので、HTTPレスポンスは圧縮されません。 そこで、圧縮を受け付けますよ、と宣言するために、HTTPリクエストヘッダに Accept-Encodingを指定します。
コマンドラインの例は、以下の通りです。
$ curl -s -H 'Accept-Encoding: gzip,deflate' 'http://localhost:8080/'
圧縮されたレスポンスは、人の目では、なんだかわかりません。そこで、ここではパイプでつないで、解凍します。
deflateで圧縮されたコンテンツは、zlibberのinflateで解凍できます。
$ curl -s -H 'Accept-Encoding: gzip,deflate' 'http://localhost:8080/' \ | inflate Hello World
Accept-Encodingにgzip,deflateの両方を指定すると、上記のプログラムは、必ず、deflateになってしまうので、gzipだけにして、レスポンスがgunzipで解凍できるか、試してみます。
$ curl -s -H 'Accept-Encoding: gzip' 'http://localhost:8080/' | gunzip Hello World
zlibber
inflateコマンドが入ってない場合は、zlibberをインストールします。
$ sudo npm install -g zlibber
関連項目
- node.jsによるHTTPサーバの作り方
- node.jsによるHTTPSサーバの作り方
- node.jsでSPDY対応ウェブサーバ
- node.js foreverでHTTPサーバをデーモン化する
- node.js HTTPサーバでApacheライクなログを記録する
- node.js HTTPサーバでレスポンスをgzipやdeflateで圧縮する
- node.js clusterでHTTPサーバをマルチプロセス化する
- zlibber
ツイート