nginxでWordPress高速化
どうも、ストロボライトでエンジニアをやっている荒木です。
いよいよ弊社でもエンジニアブログを始める、ということで、初めてのエントリを拝命しました。
まず、色々話す前に、弊社のサービスのざっくりとした説明を…
ストロボライトでは、
「LOVEGREEN」というメディアサイト
lovegreen.net
「Botapii」というフリーペーパー
botapii.jp
「MIDOLAS」という造園事業
midolas.jp
と、Green領域において多岐に事業を展開しております。
基本、開発事業部では、全ての事業を見ておりネタとしても色々とあるのですが、今回は「LOVEGREEN」にて実施した「nginx+WordPressでサイト高速化」について触れてみようかと思います。
本日のお品書き
WordPressのみのチューニングの限界
この辺りは昔から色々と誰もが試行錯誤して情報は世の中に沢山溢れていますが、高トラフィックなサイトでのチューニングとなると、WordPress単体でのチューニングには限界が出てきます。
nginxでのキャッシュを導入を検討
元々、CloudFlare + apache + php-fpm + WordPressという構成で、さくらクラウドで稼働させていたものを、AWSへ移行し、CloudFlare + nginx + php-fpm + WordPressという構成に変更しました(この辺りのお話しは、また別の機会に)
で、そこからnginxのキャッシュを使って、そもそもWordPressに処理をさせないようにします。
いわゆる、「FastCGI Cache」の導入です。
この辺りは、沢山ドキュメントが出ていますので、特に迷うこともないかと思います。
FastCGI Cacheの設定
「nginx.conf(もしくはvhostのconf)」に必要な設定を追加していきます。
# 説明① fastcgi_cache_path {キャッシュファイルを保存するパス} levels=1:2 keys_zone={キャッシュゾーン名}:100m inactive=1d max_size=10g; ## 中略 ## # 説明② set $fixed_scheme 'https'; # 説明③ set $cache_enable 0; set $keys_zone {キャッシュゾーン名}; # set $cache_enable 1; # set $keys_zone ''; # 説明④ if ($request_method != GET) { set $cache_enable 1; } # 説明⑤ if ($request_uri ~* "({キャッシュしたくないURLを|でつなぐ})") { set $cache_enable 1; } # 説明⑥ if ($http_cookie ~* "{キャッシュしたくないCookie名を|でつなぐ}") { set $do_not_cache 1; } set $is_sp ''; # 説明⑦ if ($http_user_agent ~* '({スマホと判定されるUAを|でつなぐ(例えばPhone|iPod|Androidなど)})') { set $is_sp 'sp.'; } location ~ \.php$ { ## 中略 ## # 説明⑧ fastcgi_no_cache $cache_enable; fastcgi_cache_bypass $cache_enable; fastcgi_cache $keys_zone; fastcgi_cache_key $is_sp$fixed_scheme://$host$request_uri; fastcgi_cache_valid 200 30m; fastcgi_cache_valid 301 302 30m; fastcgi_cache_valid 404 1m; fastcgi_cache_valid 500 10s; fastcgi_cache_valid any 1m; }
大分端折りましたが、ざっとFastCGI Cacheの設定周りだけ記載してみました。
そんなに特殊なことはしていません。
以下ざっと説明です。
FastCGI Cacheの各項目の説明
説明① 「fastcgi_cache_pathの設定」
ここは基本マニュアル通りに設定します。
現状ではinactiveを1日にして、全くアクセスされなかったページは1日で削除されるように設定しています。
maz_sizeは10Gにして多めにキャッシュできるようにしています。
説明② 「HTTPスキーマの設定」
基本、LOVEGREENではSSL Onlyにしているのでキャッシュ時のkey(fastcgi_cache_key)に含めるHTTPスキーマも「https」固定にしてあります。
説明③ 「変数定義」
この辺りは動的に設定する変数の定義です。
$cache_enableという変数を定義して、動的にキャッシュする、しないを切り替えられるようにしています。($cache_enable=1でキャッシュON、$cache_enable=0でキャッシュOFF)
説明④ 「リクエストメソッドでのキャッシュON/OFF」
ここではGETメソッド以外はキャッシュしないように制御しています。
説明⑤ 「リクエストURLでのキャッシュON/OFF」
キャッシュしたくないページのURLを列挙していきます。
WordPressの場合、管理画面のURL、sitemapのURL、WordPressのフォーム画面などのURLになります。
説明⑥ 「CookieでのキャッシュON/OFF」
特定のCookieを持っている場合、キャッシュしない設定をここで定義します。
WordPressの場合だと
ぐらいですね。コメント機能があるのであれば、comment_authorも入れておけばよいかと思います。
説明⑦ 「UA判定でキャッシュKeyをPC/SPで分ける」
PCとSPでURLが同じ場合、キャッシュのKey(fastcgi_cache_key)を同じにしてしまうと、PCの時にSPの画面が表示されたり、SPの時にPCの画面が表示されたりしてしまいます。
レスポンシブサイトであれば問題なさそうですが、LOVEGREENはそうではないので、キャッシュKeyをデバイスごとに判定して、PC/SPそれぞれデバイスにあったキャッシュを作成、保持して上げる必要があるので、このようにUA判定を入れています。
説明⑧ 「fastcgi_cacheの設定」
ここでfastcgi_cacheの設定を定義しています。
主な項目について説明していきます。
fastcgi_no_cache
キャッシュする、しないを$cache_enableによって設定しています。
fastcgi_cache_bypass
キャッシュでの応答有無をを$cache_enableによって設定しています。
(キャッシュが存在してもWordPressからレスポンスを返却するかどうか)
fastcgi_cache_key
ここで、実際のキャッシュする際のキャッシュKeyを生成しています。
基本、ページURL+デバイスでユニークになるように、プレフィックスで$is_spを設定するようにしています。
ざっとこんな感じです。
で、結果は?
PageSpeed Insightsで計測すると、キャッシュ導入前、導入後で以下のような結果となりました。
キャッシュ導入前 | キャッシュ導入後 | |
---|---|---|
FCP | 3.2s | 2.1s |
DCL | 5.3s | 3.3s |
まぁ、元々が遅かったので、キャッシュの恩恵は出ているのかな?と思います。
何より、Frontの描画処理でのCPU利用率が下がったので、管理画面側のレスポンスが異常に良くなりました。
(これまでは更新に3分待つとか、地獄のような状態だったので)
これによって、編集部メンバーから称賛されるという、予期しない効果も出ています。
とりあえず、あまり濃い内容ではないですが、これから開発事業部のメンバーが定期的に技術的なエントリ、たまに趣味の話など、色々綴っていきますので、よろしくお願い致します。