以前から、AMPバリデーターの「AMPBench」でAMPページをチェックすると以下のような警告(エラーではない)が出るのが気になっていました。
[WARNING] Site does not support either “If-Modified-Since” or “ETag” headers: these make amp serving more efficient
[INFO] Header entry for If-Modified-Since not found
[INFO] Header entry for ETag not found
なんだこれ?と思って調べてみると、どうやらIf-Modified-SinceとETagの双方とも、「動的コンテンツをブラウザでキャッシュコントロールするためのHTTPヘッダーのセッティング」みたいです。
この、If-Modified-SinceとETagをWordpressで設定すれば、「訪問者による2回目のアクセスからは負荷軽減ができるかも」というわけで試してみました。
目次
WordPressでIf-ModifiedとETagを利用する方法
WordPress用に、更新日を変更した時点でキャッシュが更新される仕様で書いてみました。
以下を、テーマ(子テーマ)のfunctions.phpに貼り付けます。
/////////////////////////////////////// // Last-modified と Etag ヘッダを使って動的コンテンツでもブラウザキャッシュさせる /////////////////////////////////////// add_action( 'wp','header_last_modified_and_etag', 1 ); if ( !function_exists( 'header_last_modified_and_etag' ) ): function header_last_modified_and_etag() { if (is_singular() /* && is_amp() //AMPページで使う場合はAMP用の条件分岐 */) { //Unix Epoc更新日時を取得する $modified_time = get_the_modified_time( 'U' ); // Last-modified と ETag 生成 $last_modified = gmdate( "D, d M Y H:i:s T", $modified_time ); //一意となるハッシュ(文字列) $etag = '"' . md5( $last_modified . get_permalink() ) . '"'; // ヘッダ送信 header( "Last-Modified: {$last_modified}" ); header( "Etag: {$etag}" ); // リクエストヘッダの If-Modified-Since と If-None-Match を取得 $if_modified_since = filter_input( INPUT_SERVER, 'HTTP_IF_MODIFIED_SINCE' ); $if_none_match = filter_input( INPUT_SERVER, 'HTTP_IF_NONE_MATCH' ); // Last-modified または Etag と一致していたら 304 Not Modified ヘッダを返して終了 if ( $if_modified_since === $last_modified || $if_none_match === $etag ) { header( 'HTTP', true, 304 ); exit; } } } endif;
参考 Etag と Last-modified ヘッダを使って動的コンテンツでもブラウザキャッシュさせる – PSI Labs
設定後の動作を見る
上記のようにカスタマイズして、ブラウザーのデベロッパーツールでヘッダー情報を見てみると、要求ヘッダーには以下のように表示されます。
応答ヘッダーはこんな感じです。
If-Modified-SinceとIf-Modifiedの日時が違っていたらキャッシュが更新されます。
一応、これで2回目の訪問からは、サーバーから「304 (Not Modified)ステータスコード」を返されることによりブラウザのキャッシュが利用されます。
なので、多少なりとも表示の高速化は図れるかもしれません。
Last-modifiedとEtagの難点
これらキャッシュ利用の難点は、「WordPressの更新日が変更されない限りキャッシュが更新されないこと」にあると思います。
WordPressの通常ページ等に今回のカスタマイズを仕込んでおくと、投稿を更新しない限りは、キャッシュが残った状態になります。
なので、例えば以下のような「新着記事ウィジェット」を利用している場合、どんなに投稿をポストしても、新着記事リストが更新されることはありません(キャッシュが残っている限り)。
その他にも、表示が動的に変更される「関連記事」等も投稿が更新されない限りは、同じブラウザを利用して閲覧した場合、常に同じものが表示されると思います。
なので、本文以外にも動的にコードを生成するページに、今回のカスタマイズは適さないかと思います。そういったページで利用するには、「Wordpressに対して何かしらの変更があった日付」を取得してLast-Modifiedに設定してやる必要はあるかもしれません。
ただ、そうすると頻繁にキャッシュが更新されるので、あまり意味のない設定になる気もします。
まとめ
今回試しに使用してみたLast-modifiedとEtagは、Wordpressで使用するには、そこまで有効ではないような気がします。
使用するとするならば、「ほとんど本文しか表示されないようなAMPページで利用する」とかしかないような。
しかし、AMPページの性質からいって、一見さんが多く、あまり再訪問者が来るようなページではないので、意味のない設定といえば意味のない設定になるかもしれません。
ということで、今回自作のテーマのAMPページとかにLast-modifiedとEtagの利用を検討してみたのですが、採用しないことにしました。
いつも大変、お世話になっております。
以下の条件分岐の記述について質問があります。
if (is_singular() /* && is_amp() //AMPページで使う場合はAMP用の条件分岐 */)
is_amp( )の条件はコメントされていますが、(単独記事の)AMPページのみで設定を行い、通常ページでは設定しない条件設定と解釈しております。
当初、AMPページのみで設定するようにコードを書いたが、AMPと通常ページで同じ設定のほうが望ましいので、AMPのみの条件をコメント部にして外したと言う理解でよろしいでしょうか?
また、設定するとETagが検知された旨の表示で、WARNINGは無事に消えるのですが、[INFO] Header entry for If-Modified-Since not foundの方は変わらずに(見つからない)表示されます。
お忙しいところ、恐れ入りますが、お時間ができた時にご回答頂けると大変助かります。
よろしくお願い致します。