たったこれだけ!ユーザビリティ向上策
キャッシュを活用してページ読み込みを高速化
すべてのWeb開発者にとって、パフォーマンスは最も気になる要素の1つでしょう。どんなに見栄えの良い、便利なWebサイトを作っても、ページの読み込みに時間がかかると、ユーザーは離れていってしまいます。
Webサイトのパフォーマンスを向上させるために、最も簡単かつ効果的な手法がキャッシュの活用です。キャッシュはWebサーバーから送られてきたデータを一時的に保存し、再度同じデータがアクセスされた際にそれを再利用することで、レスポンスの向上を図る仕組みです。
キャッシュには、大別するとWebブラウザなどが持つプライベート・キャッシュと、プロキシ・サーバーなどが持つ共有キャッシュの2種類があります。プライベートキャッシュはローカルPCにあるので高速ですが、初めてアクセスするデータには効果がありません。共有キャッシュは多くのユーザーが利用するので、人気のあるページはたいていキャッシュされているでしょう。これらのキャッシュを有効に活用すれば、Webサーバーの処理性能はまったく変わらずとも、ユーザーの体感的なレスポンスを改善できます。
しかし、だからといってやみくもにキャッシュすれば良いというものではありません。Webサーバーの負荷を減らそうとしてキャッシュの有効期限を長く設定してしまうと、Webサーバーのコンテンツは更新したのに、ユーザーからは以前と同じようにしか見えません。
さらに、ユーザー認証のかかった機密性の高いページが共有キャッシュに保存されると、とてもまずいことが起こります。図2を見てください。Aさんが表示したプライベートなページが共有キャッシュに保存されると、同じ共有キャッシュを使うBさんがアクセスしたときに、保存されたAさんのページが表示されてしまいます。これでは危険なWebサイトのレッテルを貼(は)られかねません。
このような事態を避けてキャッシュを有効活用するためには、Webサーバー側でキャッシュを正しく設定する必要があります。
キャッシュを設定してみよう
.htaccessに以下の行を追加すると、そのディレクトリに対するキャッシュの挙動を制御できます。
Header set Cache-Control "パラメータ1, パラメータ2..."
指定できる主なパラメータは図2「代表的なCache-Controlのパラメータ」のとおりです。この中でも最も重要なのが、どのキャッシュを有効にするかを指定する「public」「private」「no-cache」「no-store」です。図2「共通キャッシュの誤った使用法」の問題を避けるため、ユーザー認証のかかったデータには「private」を、個人情報などの機密データには「no-store」を指定するべきです。頻繁に更新されるコンテンツには「no-cache」を指定することで即座に反映されます。「no-cache」では日付比較などの更新チェックが行われ、更新がなければキャッシュを利用するので、「no-store」よりは負荷軽減が期待できます。
キャッシュの有効期限は「max-age」に秒数を指定することで設定します。実際にWebサーバーからデータを受け取った後、この秒数が経過するまではキャッシュの内容を返し、経過後はアクセスがあった時点でサーバーに問い合わせます。特に背景画像などのほとんど更新されないデータについては、極端に長い有効期限(1年とか)を設定することもよく行われます。もし変更の必要がでてきたら、上書きではなく別のURLにすることで確実に更新できます。
以上は現行のHTTP/1.1規格のキャッシュ制御方法ですが、実は古いHTTP/1.0の時代には、Cache-Controlの指定は存在しませんでした。その代わりにすべてのキャッシュを一括して無効にする、以下の指定が使われていました。
Header set Pragma no-cache
Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
もうこの時代のキャッシュはほとんど残っていないと思いますが、念のためpublic以外の指定をする際は上記の2行も加えておくと安心です。HTTP/1.1対応のキャッシュはこの指定を無視しますので、それらに影響はありません。
具体的な設定例をPDF形式のファイル(http://www.thinkit.co.jp/images/article/134/2/13422.zip)にまとめておきました(13422.zip/65 KB)。サンプルコードにはキャッシュのあり・なしの違いを比較できるページも用意してあります。設定の際の参考にしてください。