WordPress 用のプラグイン wp-cache の存在は WordPress 導入初期から知っていましたが、記事が少ないうちはそこまで重くなかったのと、実は導入したくない理由がありました。具体的なプラグインの問題、設計思想の話など。
動的生成の CMS に何が悲しくてページキャッシュが必要なのだ
Movable Type (以下 MT) と比べたとき、WordPress の最大の利点は HTML ページを動的生成することです。特にサイトを構築したてのころは、ページのレイアウトを色々変えて試そうとするものなので 🙂 何変えようが魔の再構築なしに、ただちに結果が反映される動的生成はありがたいものです。
ここで、一度生成した HTML ページをキャッシュしておくものを仮に「ページキャッシュ」と呼びます。動的生成なのにページキャッシュが入ってくると、例えば次のようなページキャッシュの余計なお世話問題が起こります。
Ktai Style と相性が悪い
携帯電話でアクセスされたとき、携帯向けによりコンパクトなページを表示する Ktai Style というプラグインを導入しています。(ためしにページ右側の QR コードを携帯でバーコードスキャンして、アクセスしてみてください 🙂 )
日本の WordPress サイトにはたいてい入っている便利なプラグインですが、これが wp-cache プラグインと相性が悪く、(おそらく) 携帯からのアクセスが先にあった場合、それをキャッシュされてしまい、PC 上で IE からアクセスしてきたユーザにもそれを見せてしまったりといった現象を確認しています。
ただ、これはその後 Ktai Style 側で公式な対策が行われて、wp-cache にパッチを当てる PHP コードが提供され解決しました。
Popularity Contest の集計と表示が動作しない
他にも人気記事を集計しリストを表示する Popularity Contest のような、常に表示結果が変わりうるようなウィジェットを導入している場合は、キャッシュとは得てして相性が悪いものです。
集計面での問題。Popularity Contest は集計データの一つとして、記事ごとのアクセス数を見ていますが、アクセス数 + 1…される前に、”フロントエンド” の wp-cache がフックして、手持ちのキャッシュから拾って結果を返してしまいます。真のアクセス数は Popularity Contest プラグインに届きません。
表示面の問題もあります。集計結果を WordPress サイト上で読者に見せるようにしている場合、いくら Popularity Contest が刻々とデータを更新していても、キャッシュの寿命が切れる (expire する) までは、古い集計結果がへばりついたままになります。
ページキャッシュのような根本的な仕様は WordPress 自体がハンドルすべき
一般に、キャッシュはあるソフトウェアにとって設計思想というか哲学の問題で、奥の深いものです。それを、wp-cache もしくは WP Super Cache という第三者の外付けプラグインが担おうとするから、おかしなことが起こります。
実は、WordPress 自身にも別の種類のキャッシュは内蔵されていて、
[code]
define(‘ENABLE_CACHE’,true);
[/code]
とやると有効になるのですが、あまり速度の向上は見られません。これは HTML ページキャッシュに対して、オブジェクトキャッシュなどと呼ばれており、WordPress 本体と SQL サーバ間のやりとりをキャッシュするものでまた種類が違います。
WordPress は、本体はできるだけ簡素にしておき、コミュニティにプラグインを自由に作ってもらうことで発展してきました。しかし、プラグインは基本的に WordPress 本体の仕様を基に作られるため、ページキャッシュのことは考えないのがデフォルトです。そのため、キャッシュを入れないと重くてしょうがない、入れるとプラグインの互換性が損なわれる、といった問題が起きてしまいます。
各自プラグイン側で対処せざるを得ないという状況も、おかしな問題です。キャッシュプラグインのデファクトスタンダードが変わってしまえば、対処方法も変わってしまうというリスクも伴います。
そういうわけで、WordCamp Tokyo 2009 でボツになってしまった昼休み質問の一つは、
WordPress には HTML ページキャッシュをなぜインテグレートしないのか
でした。動的生成 CMS のフロントエンドにページキャッシュという、観念的には利点を自ら台無しにしそうなフィーチャーでも、現実的には、WordPress ベースの記事数が増えていくにつれ、採り入れざるを得ない状態になってきているわけで、その辺 Matt としてはどう考えているんだい、といった感じの内容でした。
今度聞いてみることにしましょう。
WordCamp にご来場ありがとうございます。
質問を没にした本人です。
>WordPress には HTML ページキャッシュをなぜインテグレートしないのか
この質問自体は面白そうだったのですが、回答が長くなりそうなのと、技術的に突っ込んだ話になりそうだったので、外させてもらいました。
サーバー負荷は無視するわけにはいかないので、何らかの対策が必要になると思います。ただ、HTML レベルでキャッシュすると、動的生成のメリットの一部が失われるのも事実です。
KtaiStyle の振り分け、私がプレゼンで少し触れたログインしているかどうかで表示を変える(コメントフォーム等は標準でこうなっています)、といったインタラクティブな動作をする場合、HTML キャッシュとは相容れないので。
ことほど左様に制御しにくい cache なので、WP 本体側の API で集中管理できると良いのかなと考えています。
例えば Ktai Style では wp-cache の用意した config である wp-cache-config.php の途中に patch コードを挿入するようにしていますが、
WordPress 本体に取り込んだ HTML ページキャッシュに対して add_action / add_filter でフック引っかけて、Ktai Style が制御できるような形にできる、とか。
# 最近、別の記事ネタですが、ご本人が直接会いに来られました 🙂 歓迎光臨!
WP 本体で組み込むほうが扱いやすいのは間違いないでしょうね。プラグイン作者が他のプラグインまで考慮しなければならないのは大変なので。
たぶん Matt だけでなく、開発陣全体に提案することなのでしょうね。
プラグインwp-cacheを使うと、
Popularity Contest の集計と表示が動作しない
この点は確かに問題です。
ところで、この本文にも述べられている「以下の方法」であれば、理論上、「Popularity Contest の集計と表示が動作しない」ことは避けられるでしょうか。
—————————
実は、WordPress 自身にも別の種類のキャッシュは内蔵されていて、
define(‘ENABLE_CACHE’,true);
とやると有効になるのですが、あまり速度の向上は見られません。これは HTML ページキャッシュに対して、オブジェクトキャッシュなどと呼ばれており、WordPress 本体と SQL サーバ間のやりとりをキャッシュするものでまた種類が違います。
Popularity Contest の相性問題は、上記のものだと発生しなかったですね。
wp-cache を使用して、キャッシュ済みページの劇的な速度向上を得るか、プラグインの相性問題を重視して WP 内蔵キャッシュどまりにするかの選択になると思います。
私はちなみに、Popularity Contest を使わないで wp-cache を使用することにしました。
APC もお勧めですよ。やはり相性問題でてしまいますが。
http://www.nire.com/2009/04/wordpress-apc/