炊きたてのご飯が食べたい

定時に帰れるっていいね。自宅勤務できるっていいね。子どもと炊きたてのご飯が食べられる。アクトインディでは積極的にエンジニアを募集中です。

WordPress(Page Speed対応) - ブラウザのキャッシュを活用する


難易度

★★★大変

概要

キャッシュ(ブラウザがローカルに保存したファイルを使用して、WEBページを表示すること)を友好的に活用することで、ネットワーク経由でのファイルのダウンロード処理が省略され、サイトの高速化、サーバの負荷軽減に繋がります。

静的リソースのHTTPヘッダー内で、Expires(ファイルの有効期日)Cache-Control: max-age(最大経過時間)Last-Modified(ファイル更新日)Etag(ファイルの識別)フィンガープリントを利用した動的キャッシュ(ファイルが変更された場合にファイル名を変更)を利用して、ファイルが変更された場合は、新規に取得し、変更がない場合はキャッシュを使うように適切に設定を行います。

f:id:t-namikata:20160130133249p:plain

まずは、各用語の説明から。ブラウザキャッシュを有効にする方法は、大きく分けると次の2種類があります。

1.ファイルの確認を行わないキャッシュ(強いキャッシュで非常に高速)

Expires(表記例[Expires: Thu, 15 Apr 2013 20:00:00 GMT]) 該当のファイルは2013年の4月15日までは、キャッシュを保持するようにブラウザに指示をします。

Cache-Control: max-age(表記例[Cache-Control:max-age=86400]) キャッシュに保持しておく時間を指定します。数字の値は秒[seconds]。この例では、86400秒 = 24時間はキャッシュを保持するようにブラウザに指示をします。

ExpiresとCache-Control: max-ageは1度目のアクセスで、有効期限を取得します。それ以降のアクセスでは、有効期限が切れない限り、キャッシュを使用します。たとえ、サーバ側で更新があっても、有効期限が切れていなければ、クライアント側はファイルを更新しないので、更新が反映されないことに気をつけてください。ExpiresとCache-Controlはどちらも同じ意味あいで使用されますが、Cache-ControlはHTTP1.1をサポートしているブラウザ (現在の主流のブラウザ全て)に対し有効です。Cache-Controlの指定だけでは、HTTP1.0のブラウザに対応できない為、Expiresを併せて指定することで、より確実に動作させます。キャッシュを最大限活用するために、フィンガープリントを使った動的キャッシュがあります。フィンガープリントの説明は後述します

2.ファイルの確認を行うキャッシュ(弱いキャッシュ)

Last-Modified(表記例[Last-Modified:Tue, 16 Oct 2012 11:32:43 GMT]) ファイルの最終更新日時をクライアント(ブラウザ)にしらせるための機能です。前回訪問したときから、Last-Modified(最終更新日時)が変わっていなければ、更新されてないので、キャッシュを使ってね、を表す「304 Not Modified」ステータスコードを返却します。

Etag(表記例[etag:"00cd753e435a8dea9e187af5d2331a30"]) ブラウザがキャッシュしたファイルと、Webサーバ上のオリジナルが一致しているかどうかを決定するためのメカニズムです。最初のアクセスでブラウザはETagを取得し、2回目以降のアクセスで取得したETagをWebサーバに送り、一致すれば、更新されてないので、キャッシュを使ってね、を表す「304 Not Modified」ステータスコードを返却します。

Last-ModifiedとEtagは、1度目のアクセスで、最終更新日やファイルのEtagの値を取得します。それ以降のアクセスでは、取得した最終更新日やETagの値をWebサーバーに渡し、変更があったかどうかを確認した後、変更があれば新規にファイルを取得し、変更がなければ、Webサーバーは「304 Not Modified」を返却し、コンテンツの内容は送信せず、ブラウザはキャッシュを利用します。ExpiresやCache-Control: max-ageと異なる点は、毎回ファイルが更新されているか確認を行うところです。

設定の手順

どのようにキャッシュを行うか、考えるポイントとしては以下になります。

  1. 静的リソースは、積極的にキャッシュする
  2. 時々更新するリソースは、ファイル名にフィンガープリントを埋め込んで、キャッシュを最大限利用する

1.静的リソースは、積極的にキャッシュする

Expires、Cache-Control: max-age、Last-Modified、Etagを適切に設定します。

  1. Expiresの設定
  2. Cache-Control: max-ageの設定
  3. Last-Modifiedの設定
  4. Etagの設定

1.Expiresの設定

gzip圧縮のときと同様に、まずはhttpd.confでexpires_moduleを読み込む設定をします。

httpd.confを開き

  • mod_expires.so

で検索してください。

[bash]# vi /etc/httpd/conf/httpd.conf

LoadModule expires_module modules/mod_expires.so

/etc/init.d/httpd restart[/bash]

.htaccessファイルに下記を追記します

[bash]ExpiresActive on ExpiresByType image/gif "access plus 24 weeks" ExpiresByType image/jpeg "access plus 24 weeks" ExpiresByType image/png "access plus 24 weeks" ExpiresByType text/css "access plus 24 weeks" ExpiresByType application/x-javascript "access plus 24 weeks" ExpiresByType application/rss+xml "access plus 2 days" ExpiresByType text/html "modification plus 2 hours"[/bash]

以上でExpiresの設定は完了です。

2.Cache-Control: max-ageの設定

.httpd.confファイルに下記を追記します

[bash]<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|gz)$"> # 24weeks Header set Cache-Control "max-age=14515200, public" </FilesMatch> <FilesMatch ".(xml|txt)$"> # 2DAYS Header set Cache-Control "max-age=172800, public, must-revalidate" </FilesMatch>

下記を有効にするとwptouchのPC⇔スマートフォンの切り替えが正常に行えなくなる

<FilesMatch ".(html|htm|php)$"> # 2HOURS

Header set Cache-Control "max-age=7200, must-revalidate"

</FilesMatch>[/bash]

wptouchを利用している場合、html、phpファイルにCache-Control: max-ageを指定してしまうとPCとの切り替えが正常に行えなくなるみたいです。こう考えると、レシポンシブデザインいいな!って思いますよね。

※public、must-revalidateのオプションの説明は、ページ下部の参考サイトを確認してください。

以上でCache-Control: max-ageの設定の設定は完了です。

3.Last-Modifiedの設定

WordPressプラグイン「Head Clener」で「メタタグ "Last Modified" を追加」にチェックを入れます。

●注意 ※html5でサイトが作られている場合は、下記のような構文エラーがでます。 Error: Bad value Last-Modified for attribute http-equiv on element meta. html5では、last-modifiedの書き方がシンプルになった為です。

[html]<meta http-equiv="last-modified" content="Thu, 14 Apr 2011 12:17:27 GMT"/>[/html]

[html]<meta last-modified="Thu, 14 Apr 2011 12:17:27 GMT"/>[/html]

4.ETagの設定

.httpd.confファイルに下記を追記します

[bash]FileETag none[/bash]

Last-Modifiedを指定している場合、ETagは無効にしたほうが無難です。ETagを無効にしても、Last-Modifiedヘッダーが更新日付に基づいてキャッシングを判断してくれます。また、ETagを取り除くことで、レスポンスとそれに続くリクエストのHTTPヘッダーのサイズを減らすことができます。

2.時々更新するリソースは、ファイル名にフィンガープリントを埋め込んで、キャッシュを最大限利用する

フィンガープリントとは、デジタルコンテンツの同一性を確認するために使用される値のことである。フィンガープリントは、デジタルコンテンツをハッシュ関数で計算した結果として出力される。コンテンツのハッシュ値を照合することで、比べたデータが同一内容か、あるいは改竄された内容になっているか、判断することができる。

●フィンガープリントの説明(IT用語辞典バイナリ参照) link http://www.sophia-it.com/content/%E3%83%95%E3%82%A3%E3%83%B3%E3%82%AC%E3%83%BC%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88

時々更新するリソースのキャッシュには、ファイル名にフィンガープリントを実装することで、キャッシュを最大限に活用することができます。ファイルが変更されると、ファイル名やURLが変更になる機能があれば、自動的にブラウザは新しいファイルを要求してくるので、キャッシュ期間を長く設定することが可能になります。

例としてGoogleカレンダーがあげられます。

Googleカレンダーでは、ログイン後に表示するユーザーカレンダー用のCSSを[フィンガープリントキー]doozercompiled.cssとしています。

f:id:t-namikata:20160130133301p:plain

フィンガープリントキーは82b6bc440914c01297b99b4bca641a5d

フィンガープリントの仕組みのおかげで

  • Expiresヘッダは1年後
  • Last-Modifiedはファイルが更新された日付
  • Cache-Control: max-ageヘッダーは3153600秒

に設定し、有効期限前にファイルが変更された場合は、ファイル名が変更される為、ファイルが必ず再読込されるようになっています。

フィンガープリントの実装をWordPressでどのように実装できるのかは、これから調べていきたいと思います。

注意点

Firefoxでのキャッシュ衝突に注意 Firefoxのキャッシュファイル生成ロジックでは、計8文字しか使われておらず、比較的容易にハッシュ値が衝突してしまう可能性があります。ファイル名やページURLは、Firefoxのディスクキャッシュで使用している8文字のランダムな文字列と衝突しないように8文字より多くしたほうが良いです。

確認方法

htmlやcss、jsなど各ファイルタイプによって、期間の指定が異なるので、各ファイル毎に確認をします。 Chromeでサイトを開き、右クリックして、要素を検証。Networkタブを開き、該当のファイルを開きます。

1.静的リソースは、積極的にキャッシュする 下部のResponse Headersの各項目にそれぞれ適切な値が入っているかを確認します。

f:id:t-namikata:20160130133314p:plain

・Expires:Fri, 14 Dec 2012 08:44:50 GMT 意図した日付になっているか

・Cache-Control:max-age=public, 14515200 意図した秒数が指定されているか

・Last-Modified:Tue, 16 Oct 2012 11:32:43 GMT 最終更新日が指定されているか

・etag:"00cd753e435a8dea9e187af5d2331a30" 上記のetagの表記がなくなっているか

参考サイト

[Web] Google Page Speedでサイトを高速化(キャッシュの説明) link http://screw-axis.com/2009/06/06/web-google-page-speed%E3%81%A7%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%961/

公開前にやっておきたいサイト最適化対策(Expiresの設定) link http://higash.net/20090628/optimization.html

HTTP キャッシュ ヘッダの設定 - Cache-Control(public、must-revalidateのオプションの説明) link http://otndnld.oracle.co.jp/document/products/E13158_01/alui/wci/docs103/devguide/tsk_pagelets_settingcaching_httpcachecontrol.html

Webサイトの高速化 ルール13 ETagを正しく設定する! (ETagは難しいので、無効が無難) link http://www.inter-office.co.jp/contents/193/