ウェブサイトをgzip圧縮で高速化する

ウェブサイトをgzip圧縮で高速化する

Posted at June 19,2012 1:55 AM
Tag:[gzip, HTTP]

ウェブサイトをgzip圧縮を使って高速化するカスタマイズを紹介します。当サイトでもgzip圧縮を利用しています。

1.gzip圧縮によるウェブサイト高速化のイメージ

gzip圧縮によるウェブサイト高速化のイメージをご覧ください。

(クリックすれば拡大します)

クライアント(ブラウザ)から、あるウェブサイトの「index.html」にアクセスしたとき、リクエストを受信したサーバでは、HTTPリクエストの分析や、「index.html」の圧縮ファイル「index.html.gz」の有無などをチェックして、圧縮ファイルが返却可能であれば「index.html.gz」を返却します。

返却できない場合は通常の「index.html」をレスポンスで返却します。

圧縮ファイルを返却できれば、データの転送量を減らすことができるので、これによりウェブサイトの高速化につながります。

圧縮ファイルは受信したブラウザ側で展開することができます。主要なモダンブラウザはほぼこの機能を有しています。

2.圧縮ファイル形式

圧縮ファイル形式はgzipです。ファイルの拡張子は「.gz」になります。deflate圧縮もありますが、本エントリーでは割愛しています。

gzip圧縮する方法については、以下の記事を参考にしてください。

gzipコマンドの使い方

gzipはLinuxコマンドです。

Windowsでgzipを利用する場合、UnxUtilsやUnxUpdatesをインストールすれば、コマンドプロンプトから利用可能になります。The gzip home pageからもツールをダウンロードできるようです。WinRARでも大丈夫みたいです。

Windowsでソースコードの差分を取得する方法

Macはターミナルコマンドで普通に使えると思います。

3.圧縮可能なファイル形式

HTMLファイル、CSSファイル、JavaScriptファイルなどが圧縮可能です。

PHPも圧縮可能ですが、最初から圧縮された状態でサーバ上に配置していると肝心のサーバサイドPHP処理ができなくなるので、PHP処理を行ってから圧縮するという手はあるかもしれません。

WordPressであれば「GZIP Output」というプラグインがあります。

Movable Typeでは当ブログで「GzipFilePublisherプラグイン」を公開しています。

4.HTTPでgzip圧縮ファイルが利用可能な理由

1項で「圧縮ファイルは受信したブラウザ側で展開します」と書きましたが、そもそもブラウザが圧縮ファイルをサポートしている場合、HTTPリクエストに次のような「Accept-Encoding」ヘッダを付加します。

GET user-domain/index.html HTTP/1.1
Host: user-domain
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: */*
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

上のリクエストは、要するに「(index.htmlについて)gzip圧縮やdeflate圧縮ファイルを受けつけられますよ」ということをサーバに伝えています。

このリクエストを受信したサーバは、圧縮ファイルを返却できる場合、次のような「Content-Encoding」ヘッダを付与したレスポンス(と圧縮したファイル)を返却します。

HTTP/1.1 200 OK
Date: Thu, 31 May 2012 10:02:44 GMT
Server: Apache/2.2.8 (Win32) DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color mod_fastcgi/2.4.6 PHP/5.2.5
Last-Modified: Sat, 16 Jun 2012 06:24:56 GMT
Etag: "8000000043450-25c3-4c111066fbeff"
Accept-Ranges: bytes
Content-Length: 9667
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/javascript; charset=utf-8
Content-Encoding: gzip

レスポンスを受信したクライアント(ブラウザ)は、Content-Encodingヘッダーを見て「gzip」と設定されているので受信したファイルをgzipファイルと認識して、展開します。

5.HTMLタグの書き方

調べていてよく分からなかったのがHTMLタグの書き方です。

CSSファイルやJavaScriptファイルを圧縮した場合、link要素やscript要素に圧縮ファイル名をそのまま書くものと思ってましたが、そうではないようです。

非推奨な例

<link rel="stylesheet" href="http://user-domain/style.css.gz" type="text/css" title="Default" media="screen,tv" />
<script src="http://user-domain/foo.js.gz"></script>

圧縮ファイルを利用する場合、HTMLタグの変更は必要ありません。

推奨する例

<link rel="stylesheet" href="http://user-domain/style.css" type="text/css" title="Default" media="screen,tv" />
<script src="http://user-domain/foo.js"></script>

6.圧縮ファイルを読み込む

では圧縮ファイルはどうやって読み込むのかというと、.htaccessを利用し、リクエストされたURLの末尾に「.gz」を付与して読み込みます。

.htaccessには次のような判定条件を設定します。

  • HTTPリクエストで圧縮ファイルを許容しているか(=Accept-Encodingヘッダで「gzip」が許容されているか)
  • HTTPリクエストの末尾が「.gz」でないか
  • リクエストの末尾に「.gz」を付与したファイルがサーバに存在するか

すべての条件を満たした場合、リクエストURLの末尾に「.gz」を付与します。つまり圧縮ファイルが呼び出されたものとみなして圧縮ファイルを返却します。

条件を満たさない場合はURLの末尾に「.gz」を付与しません。

7..htaccessの解説

以下の内容を記述した.htaccessを用意し、サーバのディレクトリにアップロードします。サーバ上でviエディタ等で直接作成してもOKです。

書き方は色々あるので、他サイトの設定例も色々調べてみるといいでしょう。

RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME} !\.gz$
RewriteCond %{REQUEST_FILENAME}\.gz -s
RewriteRule .+ %{REQUEST_URI}.gz
<files *.html.gz>
AddType "text/html;charset=utf-8" .gz
</files>
<files *.js.gz>
AddType "text/javascript;charset=utf-8" .gz
</files>
<files *.css.gz>
AddType "text/css" .gz
</files>
AddEncoding x-gzip .gz

6項の説明の繰り返しになりますが、設定内容の解説です。

まず、RewriteEngineディレクティブに「on」を設定することで、Webサーバ(Apache)での書き換えエンジンを有効にします。

1つめのRewriteCondディレクティブで、HTTPの「Accept-Encoding」ヘッダでgzipが許容されていれば次に進みます。gzipをサポートしていないブラウザなどからのリクエストで、このヘッダが付与されていなければ、ここで処理が終わって非圧縮ファイルを返却します。

RewriteCond %{HTTP:Accept-Encoding} gzip

2つめのRewriteCondディレクティブで、拡張子が「.gz」でなければ次に進みます。

RewriteCond %{REQUEST_FILENAME} !\.gz$

3つめのRewriteCondディレクティブで、元のファイルの末尾に「.gz」を付与したファイルが存在すれば次に進みます。

RewriteCond %{REQUEST_FILENAME}\.gz -s

上記3つの条件を満たしたリクエストについて、RewriteRuleディレクティブでURIの末尾に「.gz」を付与して処理をおこないます。

RewriteRule .+ %{REQUEST_URI}.gz

ファイル名の末尾が「.gz」のファイルについては、ファイル種別に応じて振り分けてAddTypeディレクティブでHTTPレスポンスの「Content-Type」ヘッダを付与します。HTMLファイルには「text/html」を、CSSファイルには「text/css」を、JavaScriptファイルには「text/javascript」を付与します。「charset=utf-8」は必要に応じて設定してください。

<files *.html.gz>
AddType "text/html;charset=utf-8" .gz
</files>
<files *.js.gz>
AddType "text/javascript;charset=utf-8" .gz
</files>
<files *.css.gz>
AddType "text/css" .gz
</files>

最後にAddEncodingディレクティブを使って、HTTPレスポンスに「Content-Encoging: gzip」を付与します。

AddEncoding x-gzip .gz

すでに.htaccessを使っている場合は、ファイルの末尾または先頭に上記の内容を追加してください。

8.gzip圧縮で通信されていることを確認する

Firefoxのアドオン「Live HTTP Headers」などで確認できます。

LiveHTTPHeaders(Firefox 機能拡張)でHTTP ヘッダを表示する

普通にリロードすると304が返却される可能性があるので、Windowsの場合は「Ctrl+F5」で強制リロードするとよいでしょう。

9.CDNサービスのファイルはgzip圧縮されている

ご存知かもしれませんが、Google CDNサービスなどはgzip圧縮されたファイルを返却します。

GET /ajax/libs/jquery/1.7.2/jquery.min.js HTTP/1.1
Host: ajax.googleapis.com
User-Agent: Mozilla/5.0 (Windows NT 6.0; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: */*
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://user-domain/
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Type: text/javascript; charset=UTF-8
Last-Modified: Thu, 29 Mar 2012 18:19:50 GMT
Date: Thu, 14 Jun 2012 14:53:48 GMT
Expires: Fri, 14 Jun 2013 14:53:48 GMT
x-content-type-options: nosniff
Server: sffe
Content-Length: 33673
x-xss-protection: 1; mode=block
Cache-Control: public, max-age=31536000
Age: 344451

Google AnalyticsやGoogle Adsenseのコードも圧縮されています。

10.参考サイト

参考サイトは下記です。ありがとうございました。

11.mod_deflateについて

本題からそれますが、はてなブックマークコメントで「mod_deflateじゃダメなの?」とありました。mod_deflateはサーバでコンテンツ圧縮を行うための機能です。

ざっと調べたところ、以下の理由により、一定の条件を満たす場合のみ有効であると思われます。

  • レンタルサーバによってはmod_deflateが有効になっていない
  • サーバで圧縮を行うため圧縮コストがかかる。
関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)