header.phpと.htaccessでWordPressの読み込み速度を最適化する
ウェブサイトの読み込み速度は、すべてのブログ/ウェブサイト、特にレンタルサーバーを借りている人にとっては非常に重要です。
これは安いホスティングサービスでも有効な方法です。
ただ、日本の安いホスティングサービスというとロリポップとかになるのでしょうけど、静的なHTMLのコンテンツならかまわないでしょうけど、WordPressなどではきついです。
だから、1000円くらいの価格のレンタルサーバーを対象として方法かも知れません。
WordPressのキャッシュはいろいろ議論がありますが、いくつかのプラグインに集約されてきています。
日本では以下
個人的には以下
基本として他のサイトではプラグインの数を絞り、テーマも軽量化しろって言っています。テーマはわかるけど機能はモリモリ入れたい派なのでプラグインを60~70でも対応可能な想定
プラグインだけではなく、もう一工夫として.htaccessとheader.phpのいくつかのアイデアを加えた処理をしておくと、ウェブサイトの読み込み速度を50~70%のパフォーマンスを発揮する事が出来る事が容易になります。
Webサイトの表示パフォーマンスはWeb開発者からますます注目を集めていて、Web開発で最も注目を集めている話題の1つです。
まず第一に、ローディング速度は機能以上に重要なものです。
スピードが最も重要で必要な機能です。
ウェブサイトやブログで表示が遅い場合、閲覧者はそのサイトを使用しません。
インターネットの巨人はどのくらいのスピードを推奨しているのか:
Googleの場合500ミリ秒のな読み込み時間で20%
Yahooの場合、読み込み時間が400ミリ秒になると、ページが読み込まれる前に「戻る」をクリックした人の数が5~9%増加しました
Amazonの場合 – 余分な読み込み時間が100ミリ秒になると売上が1%減少した
Googleは、Webをより速くするための努力として「検索ランキングでサイトのスピードを考慮に入れることにしました」とブログで公表しています。
したがって、ウェブサイトが遅くなると、検索エンジンランキングも低下します。
読み込み速度は重要です。
CDN(Content Delivery System)はこの目的にはかなり良いものですが、限られた範囲で良いCDNプロバイダは少しコストがかかります。
これらに対応するために、いくつかの最も重要な速度の最適化として.htaccessの最適化を行うことでプラグインに頼らない方法で簡単に行うことができます。
これにより、コンテンツを圧縮してブラウザキャッシュを有効にすることで、あらゆるWebサイトの読み込み速度を向上させることができ、Yahoo!の卓越したパフォーマンスチームが実施したWebサイトのスピードアップの推奨事項に準拠することができます。
ステップ1 Gzip File 圧縮
Gzip圧縮は、HTTP応答のサイズを減らすことによってレスポンスタイムを短縮します。
HTML、スクリプト、スタイルシートをgzipすることが効果的です。
実際、XMLやJSONなどのテキストレスポンスを圧縮することで高速化をはかる事が出来ます。
イメージファイルやPDFファイルは、すでに圧縮されているため、gzipで圧縮しないでください。
それらをgzipにしようとするとCPUが浪費されるだけでなく、ファイルサイズが大きくなる可能性があります。
ファイル圧縮は、帯域幅のいくらかを節約するのでクラウドなどのコスト削減にも寄与するでしょう。
.htaccessで
Apacheサーバーの場合
mod_pagespeed
はGoogleによって開発されたApacheモジュールであり、そのコマンド・ディレクティブは他のモジュールと同様に使用できます。
現在のところ、GoDaddyとDreamHostだけがこのmod_pagespeed
モジュールをサポートしているので、あなたがそれらをホストしているなら、.htaccessファイルに次のコードをコピーして貼り付けてください:
<IfModule pagespeed_module> ModPagespeed on # using commands,filters etc </IfModule>
mod_pagespeed
モジュールをサポートしていない他のホスティングサービスの場合は以下の方法になります。
mod_deflate
モジュールを使うことができます(Apache 1.3xが使われてmod_gzip
いますが、Apache 2x系では mod_deflate
が使われています)
<ifModule mod_deflate.c> AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript </ifModul>
Nginxサーバーの場合
Nginx Webサーバーでホストしている場合は、ghzip圧縮を有効にするために.htaccessに以下をコピーしてください。
server { gzip on; gzip_types text/html text/css application/x-javascript text/plain text/xml image/x-icon; }
header.phpでGzipを有効化する
サーバでGzipを有効にした後に mod_deflate
か mod_gzip の
ApacheとNginxの両方で動作するgzip圧縮を以下のPHPスクリプトを使用できます
WordPressのテーマのheader.phpに以下のコードをコピーするだけです。
<?php if ( substr_count( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) ) { ob_start( "ob_gzhandler" ); } else { ob_start(); } ?>
以下はgzip圧縮を使用しない場合と使用した場合のウェブサイトのローディング速度を示す棒グラフです。
ステップ2 ETagsを無効にする
ETags(エンティティタグ)は、Webサーバーとブラウザがブラウザキャッシュ内のコンポーネントがサーバーの情報と一致するかどうかを判断するために使用するメカニズムです。
最終更新日よりも柔軟性のあるエンティティを検証するためのメカニズムを提供するためにEtagsが追加されています。
ETagは、コンポーネントの特定のバージョンを一意に識別する文字列です。
この形式の限界は、文字列が引用されることです。
サーバー情報は、ETagのヘッダーレスポンスを使用してコンポーネントのETagを指定します。
つまり、キャッシュとブラウザキャッシュの一致をアクセス毎に確認する事になるので、その分速度が低下してしまうという事実があります。
これを回避するためにはETagを無効にする必要があり、ETagを無効にするには、.htaccessファイルに以下のコードを貼り付けることで対応ができます。
Header unset ETag FileETag None
ステップ3 ブラウザキャッシュを使用する
ブラウザキャッシュは、特定のファイルに特定の時間だけブラウザで表示します。ファイルが再度必要になると、ブラウザはサーバーへ要求を出すのではなく、ローカルキャッシュから情報を引き出すことになります。
キャッシングを行わずにウェブサイトを運営することは、渇いた井戸の水を飲むためにつるべを落とす行為であり無駄な労力の多い対応です。
それは実用的ではないだけでなく、より多くの作業が必要になります!
ユーザーがアクセスをするたびにサーバーでデーターを作成してブラウザにそのデータを渡す事になるので、有効な方法とは思えません。
ブラウザキャッシュすることは、リピートユーザーを得るためには必要な方法です。
つまり、あなたのサイトへ良く訪れてくれる人にはより快適な環境を提供することで友好的な訪問者をあなたにサイトへ築くことができ、多くの帯域幅を節約することができるのでクラウドのコスト削減にも有効に働きます。
ページを初めて訪れると、サイトのすべてのファイルをダウンロードするようにいくつかのHTTPリクエストが行われますが、ExpiresおよびCache-Controlヘッダーを使用すると、それらのファイルをキャッシュ可能にします。
これにより、後から来た別の訪問者には不必要なHTTPリクエストが発生することがなくなります。
Apacheサーバーの場合
Apacheは、mod_expires
および mod_headers
モジュールで有効になります。
この mod_expires
モジュールは、サーバーレスポンスのExpires HTTPヘッダーとCache-Control HTTPヘッダーのmax-ageディレクティブの設定を制御します。
max-age 以外の Cache-Control ディレクティブを変更するには、mod_headers
モジュールを使用します。
この mod_headers
モジュールは、HTTPリクエストおよび応答ヘッダーリクエストを制御および変更するための指示を提供します。
ヘッダーリクエストは、マージ、置換、または削除することができます。
Expiresヘッダーを設定するには、以下のルールを.htaccessに追加します。
# BEGIN Expire headers <ifModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 5 seconds" ExpiresByType image/x-icon "access plus 2592000 seconds" ExpiresByType image/jpeg "access plus 2592000 seconds" ExpiresByType image/png "access plus 2592000 seconds" ExpiresByType image/gif "access plus 2592000 seconds" ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds" ExpiresByType text/css "access plus 604800 seconds" ExpiresByType text/javascript "access plus 216000 seconds" ExpiresByType application/javascript "access plus 216000 seconds" ExpiresByType application/x-javascript "access plus 216000 seconds" ExpiresByType text/html "access plus 600 seconds" ExpiresByType application/xhtml+xml "access plus 600 seconds" </ifModule> # END Expire headers
Cache-Control HTTPヘッダーを設定するための.htaccess規則
# BEGIN Cache-Control Headers <ifModule mod_headers.c> <filesMatch ".(ico|jpe?g|png|gif|swf)$"> Header set Cache-Control "public" </filesMatch> <filesMatch ".(css)$"> Header set Cache-Control "public" </filesMatch> <filesMatch ".(js)$"> Header set Cache-Control "private" </filesMatch> <filesMatch ".(x?html?|php)$"> Header set Cache-Control "private, must-revalidate" </filesMatch> </ifModule> # END Cache-Control Headers
注意:
- モジュールの
max-age
によっては既に設定されているため、Cache-Controlヘッダーでmod_expires
の指示を設定する必要はありません、 must-revalidate
のレスポンスが古くなると再確認しなければならないことを意味します。毎回チェックする必要があるわけではありません。
ステップ4 MySQLデータベースのサイズを小さくする
WordPress 2.6移行で、WordPressは投稿がMySQLデータベースにリビジョンとして保存された後も書き込む間に投稿を自動保存します。大規模なサイトのデータベースでは、サイトの読み込み時間も長くなります。リビジョン機能を削除することをお勧めします。
wp-config.phpに以下を貼り付けてリビジョンを無効にします。
define('WP_POST_REVISIONS', false );
リビジョン機能を維持したい場合は、リビジョンを一定の日数、たとえば10日間だけデータベースに保存することを選択することもできます。
もっと…
期限切れヘッダーを追加しても、最初の訪問のウェブサイトの読み込み時間には影響しませんが、来訪者からの次のページビュー/訪問のためにページの読み込み量がどのくらい減少するのかは驚きです。
あなたのサイトがどのように動作しているかを追跡します:クエリと時間の読み込み数を表示しできます。
あなたのテーマのfooter.phpのコピーライトなどの情報を設置している部分に以下ののコードを貼り付けてください。
<?php echo get_num_queries(); ?> queries in <?php timer_stop(1); ?> seconds.
ブログやウェブサイトの読み込み時間を最適化するためは、他にも方法がありますが今のところ、手動で設定をする方法としてはこのような方法が最適かなと考えています。
HTTP/2とPHP7でも引き続き実験。