SEOにも効果のある WEBサイトの高速化(LAMP環境の高速化)
と
と
の続きです。
レスポンスの速さ
今まで3回の記事では一般的なSEO対策といわれるどちらかというとテクニック的なものを書きましたが、なんといってもSEががんばれる範囲でユーザーの満足度を一番上げるのはやっぱり レスポンスの速さ です。
多少ページの構成が見やすくて格好良くても、遅いサイトというのは敬遠されます。私もWEB系のSEなので、絶えずインターネットは見ていますが、googleの検索結果に表示されて、目的のページだと思ってクリックしても、表示が遅いだけでページが全部表示される前に別のページに遷移してしまったりします。
特に1日に1回巡回するようなポータルサイトや会員制サイトではレスポンスの悪さが一番気になります。
WEBサイトのサーバーサイドの高速化のアプローチは大きく分けて3つ
WEBサイトのサーバーサイドの高速化は以下の3種類に分かれます。
実施のし易さは1、2,3の順ですが、費用対効果の高さで言えば2が1番大きいです。
- WEBサーバー(アプリケーションサーバー含む)のチューニング
- DBサーバーのチューニング
- アプリケーション自体のチューニング
私の運用しているWEBサイトはいわゆるLAMP環境でアプリケーション部分はPHPですが、そちらで行った内容を簡単にご紹介します。
WEBサーバー(アプリケーションサーバー含む)のチューニング
WEBサーバー側の高速化で行ったのは以下3つです。
apacheの不要なモジュールの読み込みを停止
apacheは不要なモジュールを沢山読み込んでいるので、こちらを止めるだけで、メモリの使用量が思ったより減らせます。実際に設定したところ、アクセスがまったくない状態でもメモリの使用量が3割くらいは減りました。
通信をgzip圧縮する
gzip圧縮については googleのPageSpeed Insights やyahooのYSlowなんかのサイトパフォーマンスを計測ツールでも実施すべき項目として出るのですが、Webサーバーからクライアントのブラウザにコンテンツを返す際にコンテンツを圧縮して返す方法です。テキストが多いサイトについては圧縮が効くので効果が高いです。こちらの設定をした効果ですが、帯域の使用量が、1割くらいは変わりました。
画像の有効期限の設定(EtagとExpiresの設定)
EtagとExpiresの2種類の設定を行いました。
EtagはWebサーバーがファイルを返す際にHTTPヘッダーの中に埋め込んで渡す値で、次回同じコンテンツを取得しようとした際にブラウザがこちらの値をWEBサーバーにリクエストと一緒に渡し、ファイルに差がなければWEBサーバーはHTTPステータスコード304(Not Modified;更新がない)を返します。そうすると、ブラウザはローカルのキャッシュの中のファイルを利用するため、実際のファイルを送信するよりも帯域を使用せず、レスポンスが良くなります。
ExpiresもWebサーバーがファイルを返す際にHTTPヘッダーの中に埋め込んで渡す値ですが、こちらはパラメーター名そのままで、返したファイルの有効期限がセットされています。次回表示しようとした際に、こちらの有効期限を見て、期限が過ぎていなければWEBサーバーにリクエスト自体を投げません。通信が発生しないので、当然帯域も使わずレスポンスが良くなります。
こちらの2つの設定は体感速度自体あがったようには感じなかったのですが、回線状況が悪い場所などでは効果があると思います。
アプリケーションサーバー側のチューニング
アプリケーションサーバー側の高速化で行ったのは以下1つです。
- APC ( Alternative PHP Cache )の導入
こちらは PHPの中間コードをメモリ上にキャッシュすることで高速化する仕組みで、インストールすればPHP全般が早くなります。これは体感できるくらい早くなります。
DBサーバーのチューニング
に関しては一般的なパラメータの調整(主にメモリ関連)を行いましたが、アプリケーションのチューニングのために、処理に時間がかかった(3秒以上)SQLについてはログに出力する設定(slowquery)を本番環境に行いました。
アプリケーション自体のチューニング
これが一番時間がかかるのですが、個別のページや機能自体で特に遅くなっているSQLをDBのslowqueryから洗い出してチューニングしました。
具体的にはよく言われるインデックスを効かせたり、必要な分だけデータを取得するように修正するなど一般的なチューニングです。
更に踏み込んで、DBの設定で実行したSQLは全てログに出力するようにして、
ユーザーの属性によって取得結果の違うSQLはユーザー毎にキャッシュし、同じユーザーからアクセスがあった場合はその結果を使うようにしました。
また、ユーザーの属性によらない共通のSQLの結果もキャッシュし、全てのユーザーで使いまわすようにしました。
アプリケーションの構成上、ユーザーの属性に合わせてコンテンツを抽出する部分とコンテンツ毎のタイトルや本文など共通の情報を取得するSQLが分かれていたので、このような2段階の対応をしました。
全ての対応の結果
- HTMLのレスポンスタイムの平均が2倍以上早くなった
- アクセスのピークタイムでも通常の時間と変わらないレスポンスタイムになった
- サーバーの負荷が一気に下がった
- 1ページ表示する時に多いと500回以上SQLを投げていたのが100件以下になった
全部で2ヶ月近くかかったのですが、効果は絶大で、最初に返すHTMLのレスポンスタイムの平均が2倍以上早くなりました。(0.6秒ちょっと → 0.25秒前後)
また、アクセスのピークタイムではレスポンスが遅くなり、サーバーの負荷も上がってしまっていたのですが、共通のSQLの結果の使い回しが効いた結果、ピークタイムでも通常の時間帯と変わらないレスポンスタイムでHTMLを返せるようになりました。
ピークタイム時のサーバーの負荷についてもWEBサーバーの負荷はそれほど上がらなくなり、DBサーバーに至っては通常の時間帯の負荷と変わらなくなりました。
地味な作業でしたが、体感できるぐらい早くなり大変満足しています。