今回はHTMLやCSS、Javascriptといった比較的軽量な静的コンテンツの配信をnginxでやるケースに絞ってチューニングする際のポイントについて紹介しようかと思います。
(注:worker_rlimit_nofile
やsysctl.confのネットワーク周りの設定のような定石的なチューニングについてはあえて解説しないのであらかじめご了承ください。)
コンテンツをgzip圧縮する
何はともあれgzip圧縮です。ネットワーク帯域に比べればCPUリソースなんて安いものです。
# コンテンツをgzip圧縮する
gzip on;
しかし、多くの場合これだけでは十分ではありません。何故ならnginxはデフォルトではContent-Typeがtext/html
のコンテンツしか圧縮しないためです。圧縮対象のContent-Typeを増やすにはgzip_types
を使います。
# text/htmlはgzip onであれば常に圧縮される
gzip_types text/css text/javascript;
単純なWebサイトであれば上記の設定で十分ですが、場合によってはapplication/json
やapplication/javascript
といったContent-Typeを加えるのもよいでしょう。
また、Apacheのmod_deflateと違ってnginxのgzip圧縮モジュールはgzip_vary on;
と書かないとコンテンツをgzip圧縮した際にVary: Accept-Encoding
を付加しないので注意しましょう。
gzip_staticモジュールで圧縮済みのコンテンツを配信する
「ネットワーク帯域に比べればCPUリソースなんて安いものです」とは言ったものの、やはり配信量が増えてくるとgzip圧縮によるCPUリソースの消費も無視できなくなってきます。
そういった場合に有効なのがgzip_static
です。通常nginxでコンテンツのgzip圧縮を有効にした場合(gzip on
)、コンテンツを配信する際に毎回コンテンツのgzip圧縮を行いますが、gzip_static
を有効にすると既に圧縮済みのファイル(e.g. xxx.js.gz)があればそれをそのまま配信します。なのでこの機能を使うとCPUリソースを大幅に節約できます。また、gzip圧縮をサポートしていないクライアントにも配信する場合はgunzip
を利用してgzファイルを展開するようにしましょう。
# xxx.(css|js).gzが存在したらそれをそのまま配信する
# また、クライアントがgzip圧縮をサポートしてない場合はgzファイルを展開して配信する
location ~* \.(css|js)$ {
gzip_static always;
gunzip on;
}
あと、gzip_static
とgunzip
を利用するにはnginxのconfigure実行時に--with-http_gzip_static_module
と--with-http_gunzip_module
のオプションが必要です。
zopfliでさらに圧縮する
zopfliはgzipやzlibが利用しているdeflate互換の圧縮アルゴリズム(とその実装)です。
deflateと互換性があるのでzopfliで圧縮したコンテンツはdeflateで展開することができます。加えてzopfliはdeflateよりも圧縮率が高い(数%)という利点があります、その反面圧縮にかかるコストはdeflateに比べて非常に高いので、nginxでコンテンツを配信する際に毎回zopfliで圧縮するといったようなことは現実的ではありません。
しかし、gzip_static
を利用しているのであれば話は別です。先述の通りzopfliはdeflateと互換性があります。zoplfliで圧縮したファイルはdeflateで展開可能なのでzopfliで圧縮したgzファイルをgzip_static
で配信すればよいわけです。
expiresでクライアントにキャッシュさせる
コンテンツを圧縮することでネットワーク帯域を節約できるのはよいことですが、もっと帯域を節約できるよい方法があります。それは一度アクセスしてきたクライアントには自身のキャッシュを利用するようにして配信サーバ自体は304を返すようにすることです。
今回は静的コンテンツの配信なのでnginxの場合は以下のようにexpires
を設定するだけで十分でしょう。
expires 30d;
expires
は結構書式がいろいろあってややこしいので詳しくは本家のドキュメントをご覧ください。
open_file_cacheで配信コンテンツのファイル情報をキャッシュする
open_file_cache
を利用するとファイルディスクリプタやサイズ、更新時間といった情報をキャッシュすることができます。
# キャッシュのエントリー数(max)とアクセスがないキャッシュの有効期間を設定
open_file_cache max=100 inactive=10s;
主にファイルのopenやcloseに伴うシステムコールのオーバーヘッドを軽減する効果があります。