やりたいこと
- サーバの CPU 負荷、ネットワークの負荷を抑制したい
- ユーザから見た、サイトの応答速度を向上したい
実現方法
- .gz ファイルを事前に生成し、可能なら Apache から直接そのデータをブラウザに返す
- mod_deflate なら返すときに圧縮するので CPU 負荷がかかるが、この方法ならそれを節約できる
前提
- .html、.css 、.js の3種類だけを対象に
- .gz ファイルは事前の生成が必要
- Ruby on Rails なら、rake assets:precompile で作られる
- 自分で .gz ファイルを生成するなら、下記のようにする
$ find public -name "*.html" -o -name "*.css" -o -name "*.js" | \
xargs -ifile sh -c "gzip --best -c file > file.gz"
設定例( Apache )
もちろん、 /home/cuzic/railsapp のところは適切に設定すること。
httpd.conf
<Directory /home/cuzic/railsapp/public>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/portal/$
RewriteRule ^(.*)$ /portal/index.html
# RewriteCond %{HTTP:Accept-Encoding} \b(x-)?gzip\b
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_URI} (\.js|\.css|\.html)$
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule .* %{REQUEST_URI}.gz [last]
</Directory>
<FilesMatch "\.html\.gz$">
ForceType text/html
Header set Content-Encoding gzip
</FilesMatch>
<FilesMatch "\.css\.gz$">
ForceType text/css
Header set Content-Encoding gzip
</FilesMatch>
<FilesMatch \.js\.gz$>
ForceType text/javascript
Header set Content-Encoding gzip
</FilesMatch>
ひとりごと
-
find 関連
- find は -o で OR 条件のフィルタが書けて便利
- find の exec を使うより、パイプで xargs を使う方が動作が速くてオススメらしい。
-
gzip はふつうにやると元のファイルが消えて、圧縮後ファイルのみが残るのにハマった
-
mod_rewrite の ディレクトリコンテキストと、サーバコンテキストの違いがハマった
-
REQUEST_FILENAME はディレクトリコンテキストでないと、期待する動作をしない
-
index.html の扱いを忘れていて、これまたハマった
-
AddEncoding はあってもなくても動作の違いがよく分からなかった
-
「 Header append Vary 」を書いた方がいいという情報もあったが、よく分からなかった
-
昔のブラウザを考慮する場合はもっと複雑な条件分岐が必要らしい
- モダンな環境ということで全部省略した。