コンポーネントを圧縮しよう!

最近のブラウザであれば gzip 圧縮されたファイルを送信すれば、ブラウザが圧縮解除して解釈してくれるので、できるだけ gzip 圧縮して送信して転送量を減らそうと言う提言。
CSS / JavaScript / html などのテキストファイルについては、結構効果的だ。
Wordpress の記事本文については、管理画面で設定変更することによって gzip 圧縮転送ができるが、CSS / JavaScript に関しては、設定してやらなければ gzip 転送はされない。

Web サーバとして Apache を採用しているならば、mod_gzip または mod_deflate を設定するのが、現実的だろう。

が、さくらのレンタルサーバでは、どちらのモジュールも使用できない模様。

gzip 圧縮したファイルを用意しておく

あらかじめ、gzip 圧縮したファイルを用意しておいて gzip 圧縮に対応しているブラウザからのリクエストが来た場合は mod_rewrite で置き換えてしまう。
毎回 gzip 圧縮をかけているとサーバに負担を掛けちゃうので、結構効果的だと思う。
ただ、内容を変更した場合は gz ファイルも直しておかなければならないので注意が必要。

css / JavaScript ファイルと同一ディレクトリに gzip 圧縮したファイルを hoge.js.gz 等の名前をつけて保存しておき、.htaccessに以下を追加すれば、実現可能。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME} "\.(css|js|html?|xml)$"
RewriteCond %{REQUEST_FILENAME} !"\.gz$"
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule .+ %{REQUEST_URI}.gz [L]
</IfModule>

要求されたファイル名と同じ名前で、末尾に .gz が付いているファイルがあれば、そちらを出力してくれる。
# /js/hoge.js がリクエストされた場合、 /js/hoge.js.gz ファイルがあれば、そちらを出力。

php + mod_rewrite

Expiresヘッダを追加した際の php スクリプトを若干修正することで、対応することもできる。
ただし、こちらは毎回 gzip 圧縮をかけるようになるため、サーバの負担はバカにならない。

<?php
$file_found = false;

if (isset($_GET&#91;'file'&#93;)) {
 $filename = str_replace('http://'.$_SERVER&#91;'SERVER_NAME'&#93;.'/','/',$_GET&#91;'file'&#93;);
 $filename = dirname($_SERVER&#91;'SCRIPT_FILENAME'&#93;).$filename;

 if (file_exists($filename.'.gz')) {
  // gzip 圧縮されたファイルがあれば、そちらを出力
  $filename .= '.gz';
  header('Content-Encoding: gzip');
  $file_found = true;

 } elseif (file_exists($filename)) {
  // html, css, js, xml ならば gzip 圧縮して出力
  $path_info = pathinfo($filename);
  switch($path_info&#91;'extension'&#93;) {
   case 'html':
   case 'htm':
   case 'css':
   case 'js':
   case 'xml':
    ob_start("ob_gzhandler");
    break;
   default:
    break;
  }
  unset($path_info);
  $file_found = true;
 }
}

if ($file_found) {       // ファイルが有った場合、Expires ヘッダ付きで出力
 // Last-Modified ヘッダも送信
 header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($filename)).' GMT');

 // コンテンツの有効期限は 365 日
 $offset = 60 * 60 * 24 * 365;
 header('Expires: '.gmdate('D, d M Y H:i:s', time() + $offset).' GMT');

 readfile($filename);

} else {                  // ファイルが無かった場合 404 エラーを返す
 header('HTTP/1.1 404 Not Found');
}
?>

注意:

このコードにはセキュリティに対する脆弱性が存在しています。
# 生で打ち込むことによって、アクセス権を与えていないファイルにもアクセスできるようになる。
もし、使用する場合はその辺の対策を行ってから使用してください。

キモは ob_start("ob_gzhandler"); で、これを呼び出すと出力時に gzip 圧縮をかけて送信してくれる。
CSS / JavaScript を php で作成しているプラグインなんかも、これを追加してやれば gzip 圧縮してくれるようになる。

1 thought on “コンポーネントを圧縮しよう!

  1. ピンバック: WordPressのJavaScriptやCSSをまとめてgzip圧縮転送 - Markovian.org

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください