gzip compression can reduce file size. But is it needed on every HTTP request?

前回の続きの話。

前回はhtml、css、jsファイルなどのテキストファイルに対して、gzip圧縮をかけるとネットワーク転送量を大幅に減らすことができ、heroku Ceder stack上で動かしているwebrickで、自動的に圧縮する方法について書いた。これはこれで便利だけれども、じゃあリクエスト毎に圧縮する必要はあるのかい?というと、実はなかったりする。

Octopressを使っている限りでは、生成されるhtmlファイルは静的なファイルなので、リクエスト毎に変わるわけではないし、publishする前にgzip圧縮できればベスト。gzip未対応のブラウザも今はほぼないだろうし。

How can we do it? We can make Rake tasks!

Making Octopress Fastという記事では、ページ転送を高速化する方法として、Rakeのタスクを追加する方法が紹介されている。

  1. HTTPリクエストの数を減らす
  2. HTTPレスポンスの圧縮(css、jsのminify・gzip圧縮)
  3. 画像ファイルの最適化
  4. アセットファイルのバージョニング
  5. Amazon S3へのデプロイ
  6. デプロイタスク

今回はgzipタスクの部分だけを抜粋して紹介する。

Rakefile
desc "GZip HTML"
task :gzip_html do
puts "## GZipping HTML"
system 'find public/ -type f -name \*.html -exec gzip -9 {} \;'
# Batch rename .html.gz to .html
Dir['**/*.html.gz'].each do |f|
test(?f, f) and File.rename(f, f.gsub(/\.html\.gz/, '.html'))
end
end
desc "GZip CSS"
task :gzip_css do
puts "## GZipping CSS"
styles_dir = "#{public_dir}/stylesheets"
system "gzip -9 #{styles_dir}/all.#{asset_version}.css"
system "mv #{styles_dir}/all.#{asset_version}.css{.gz,}"
end
desc "GZip JS"
task :gzip_js do
puts "## GZipping JS"
scripts_dir = "#{public_dir}/javascripts"
system "gzip -9 #{scripts_dir}/all.#{asset_version}.js"
system "mv #{scripts_dir}/all.#{asset_version}.js{.gz,}"
end
desc "GZip All"
task :gzip => [:gzip_html, :gzip_css, :gzip_js]

なお、参考元の記事では、cssのminifyにcleancss、jsのminifyにuglifyjsを使っているが、どちらもYUI Compressorで対応可能なはずだ(まだ試してない)。また、バージョニングのところでは、jsファイルはheadタグのなかに書いていると記載されているが、これはasync属性を付けてやることでブラウザのレンダリングブロックを回避しているようだ。そんなわけで、タスクがシンプルになっている。

Conclusion

予めgzip圧縮しておくことでwebサーバー、またはアプリケーションサーバーに負担をかけずに転送量を減らすことができるようになった。圧縮済みなので、gzipにかかるオーバーヘッドも無くなる。

その他、フロントエンドにまつわる高速化のtipsについては、以下の記事や、オライリー本などが多いに参考になる。

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

続・ハイパフォーマンスWebサイト ―ウェブ高速化のベストプラクティス

オプティマイジングWebサイト ―SEO・サーバ・クライアントの最適化技術

Reference

Tool