mt-search.cgi のタグ検索結果ページをキャッシュさせてサーバー負荷軽減と表示速度を爆速にする方法

MTでタグクラウドなど、関連するタグが付いた記事を一覧表示させる機能がありますが、通常のままではクリックされる度にmt-search.cgiが動いて再構築イベントが発動してページが生成されて表示になります。普通にページ数が少なかったり、閲覧される人数が少ない場合はまあこれでもさしたる問題はないのですが、ページが増えてきたりすると、表示にすごく時間がかかったり、さらにはGooglebotにリンクを叩かれまくったりして、ものすごいサーバーに負担がかかるようになってきます。ほんとに。

今回紹介するのは、一度再構築イベントで生成されたページをファイルに書き出しキャッシュとして利用することにより、ページの読み込み速度を高速にし、サーバーの負荷問題も解消されるというもの。
要するに、初回にタグリンクをクリックした人は通常通り再構築が発生するが、二回目にクリックした人はすでに生成されたキャッシュを見に行くので、通常のHTMLファイルを読むのと同じ速度で閲覧することが可能となる。そして、生成されたキャッシュは該当する記事が更新されたタイミングで消されるので、情報が古くなることもない。
素晴らしいです。MT標準機能にしてほしい。MovableTypeを使っているならみんな導入すべきだと思う。

これらのことは、何故かあまり流行っていないというか知られていない、コンテンツを指定されたファイルに書き出すためのプラグイン FileWriter を使って実現します。

手順は、FileWriterプラグインを提供されているサイトでタグ検索キャッシュ記事が丁寧に書かれていますので、そちらを参考にしてください。ちなみに導入条件として、.htaccessで mod_rewrite が使用可能なサーバーに限ります。
参考: FileWriter を使ってタグ検索の結果をキャッシュする

以下に紹介する手順は主に自分用まとめです。流用する場合はサーバー環境に応じて修正して使用してください。
<検索結果ページが長く、2ページ目、3ページ目となる場合の対応>

1. FileWriter プラグインをインストールする

コンテンツをファイルに書き出す MovableType プラグイン:FileWriter からFileWriter v0.10をダウンロードして、plugins フォルダにアップロードする。

2. システムテンプレートの「検索結果」テンプレート全体を FileWriter ブロック タグで囲む

以下のように、現在使用している検索結果テンプレートをそのまま囲んでしまう。
ちなみに、ハイライト部分の archive/tag/ フォルダにキャッシュが保存されるので、もしキャッシュフォルダを変えたいならこの部分の記述を変更する。また、作成される archive/tag/フォルダはサーバー上に予め用意しておく。

<mt:IfTagSearch>
  <mt:If tag="SearchResultCount">
    <mt:SetVarBlock name="file_writer_path">archive/tag/<$mt:SearchString$>_<$MTCurrentPage$>.html</mt:SetVarBlock>
  </mt:If>
</mt:IfTagSearch>
<mt:FileWriter path="$file_writer_path">
・・・
~ 検索結果テンプレートの記述全文 ~
・・・
</mt:FileWriter>

3. .htaccess で mod_rewrite を記述する。

キャッシュ存在の有無を調べてなければ再構築、あればキャッシュを見に行くようにする。
.htaccess に以下のように追記する。
archive/tag や cgi-bin/mt/mt-search.cgi の指定は各自サーバー環境に合わせて変更してください。
また、最後の方に記述してある limit=20 は1ページに表示する記事の数なので、これも各自のサーバー設定に合わせて変更。 

# FileWriterタグ検索キャッシュ
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^archive/tag/(.+)_(.+)\.html$ /cgi-bin/mt/mt-search.cgi?tag=$1&IncludeBlogs=1&limit=20&page=$2 [NE,L]

4. キャッシュを失効させるキーの設置

いつまでもキャッシュが残り続けると、古い情報のままになってしまいますので、記事を更新や新規投稿したタイミングで、その記事に関連するタグのキャッシュを消去するようにします。
ブログ記事/ウェブページの個別アーカイブ テンプレートの一番下に以下を追記する。
※HTML上には出力されないので</html>の後でもOK

<mt:EntryIfTagged>
 <mt:EntryTags>
 <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_1.html</mt:SetVarBlock>
 <$mt:RemoveFile path="$cache_path"$>
 </mt:EntryTags>
</mt:EntryIfTagged>

上記の例はTagName_1.html しか消去してないので、2ページ目、3ページ目と長い場合はTagName_2.htmlとかも消すように各自でカスタマイズしてください。例えば以下のように<$MTTagCount$>を使って実現可能です。

<mt:EntryIfTagged>
  <mt:EntryTags>
    <mt:setvarBlock name="tagCount"><$MTTagCount$></mt:setvarBlock>
    <mt:If name="tagCount" gt="60">
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_1.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_2.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_3.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
    <mt:ElseIf gt="40">
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_1.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_2.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
    <mt:ElseIf le="20">
      <mt:SetVarBlock name="cache_path">archive/tag/<mt:TagName>_1.html</mt:SetVarBlock>
      <$mt:RemoveFile path="$cache_path"$>
    <mt:Else></mt:If>
  </mt:EntryTags>
</mt:EntryIfTagged>

5. 最後にタグクラウド等のタグリンクURLを変更する。

生成されたキャッシュを先に確認しにいってもらわないと、キャッシュの意味がないので、サイト上にあるタグリンクをキャッシュリンクに変更する。

例えば、既存にあるウィジェットのタグクラウド

<div class="widget">
  <h3>タグクラウド</h3>
  <ul class="tagCloud"><mt:Tags top="20">
    <li class="rank-<$mt:TagRank max="10"$>"><a href="javascript:void(0)" onclick="location.href='<$mt:TagSearchLink encode_js="1"$>';return false;" rel="tag"><$mt:TagName$></a><span><$MTTagCount$></span></li>
  </mt:Tags></ul>
</div>

これを以下のように変更する。

<div class="widget">
  <h3>タグクラウド</h3>
  <ul class="tagCloud"><mt:Tags top="20">
    <li class="rank-<$mt:TagRank max="10"$>"><a href="/archive/tag/<mt:tagName encode_url="1" />_1.html"><$MTTagName$></a><span><$MTTagCount$></span></li>
  </mt:Tags></ul>
</div>

最後にタグリンクが全て変更されるように、サイト全体を再構築する。
後は、自分でarchive/tag/ にファイルが生成されているか、記事を更新したときにarchive/tag/ から該当するタグのファイルが削除されるか、タグリンクをクリックしたときに、一回目はいつも通りだけど二回目クリックしたときに爆速になっているか確認してください。
できてなかったら、どこか記述が間違っているか、プラグインのインストールが上手くいっていないかが原因です。
特に .htaccess の mod_rewrite はデリケートな箇所ですので、他の動作に影響していないかよく確かめてください。