ウェンブ

フロントエンドエンジニア うぇびんのよしなし語り

a-blog cmsの「IFブロック」でどのくらい表示が遅くなるのか調べた

a-blog cmsではバージョン2.0から、テンプレート内で、グローバル変数・エントリーの情報・カスタムフィールドの値を使った「条件分岐」ができるようになりました。

IFブロック | テンプレート | ドキュメント | a-blog cms 制作者向け情報

a-blog cmsは他のCMSと比べて、細やかな表示調整が難しかったのですが、IFブロックの追加によって、METAタグやエントリーのループ内などの自由度が大幅に上がりました。

さて、私はCMSのテーマ制作のときに、「エントリーの繰り返し部分」がカスタムフィールドなどの条件によって微妙に変わる場合、条件分岐で分けてからループごとインクルードという書き方をよくします。
条件分岐の内部の行数が多いほど、ソースコードが読みにくくなり、修正や改修がしにくくなるためです。

// Movable Typeの場合
<mt:Hoge setvar="mt_hoge" />
<mt:If name="mt_hoge" eq="1">
<mt:Include module="モジュール::エントリー繰り返し部分01" />
<mt:ElseIf eq="2">
<mt:Include module="モジュール::エントリー繰り返し部分02" />
<mt:Else>
<mt:Include module="モジュール::エントリー繰り返し部分デフォルト" />
</mt:If>
// WordPressの場合

<?php 
$field_hoge = get_post_meta($post->ID, 'hoge');
if($field_hoge[0] == '1') {
  get_template_part('entry', 'loop01');
} elseif($field_hoge[0] == '2') {
  get_template_part('entry', 'loop02');
} else {
  get_template_part('entry', 'loop_default');
}
?>
// a-blog cmsの場合

<!-- BEGIN entry:loop -->
	<!-- BEGIN_IF [{hoge}/eq/1] -->
		<!--#include file="/include/entry_loop01.html"-->
	<!-- ELSE_IF [{hoge}/eq/2] -->
		<!--#include file="/include/entry_loop02.html"-->
	<!-- ELSE -->
		<!--#include file="/include/entry_loop_default.html"-->
	<!-- END_IF -->
<!-- END entry:loop -->

ですが、a-blog cmsでは、こういう書き方をすると負荷が大きくなるのでは…という疑問が出てきました。
a-blog cmsのIFブロックは、テンプレートの処理のいちばん最後となるため、条件を満たしていない箇所もすべて解析してから処理している可能性が高そうなのです。

IFブロックを使わなかった場合と、どのくらい処理速度が変わってくるのか、詳しく調べてみることにしました。

検証内容

まず、以下の内容のCSVデータを1000件ずつ、2カテゴリー分用意して、a-blog cmsにインポートしました。

  • h3とpユニットをひとつずつ登録
  • 0か1のカスタムフィールド「fieldTest01」
  • 5種類の値からひとつを選択するカスタムフィールド「fieldTest02」
  • 4種類の値から任意に選ぶカスタムフィールド「fieldTest03」


続いて、そのデータをもとに、以下の6パターンのモジュール処理時間を、a-blog cms内蔵のベンチマークモードで計測しました。
サーバーは、エックスサーバーのX20プランで、a-blog cmsのバージョンはデータベース処理が改良された最新バージョン、2.5.1です。やや処理が遅くなる「ディベロッパーモード」がオンになっています。

条件分岐・インクルードなし 1 「test01」カテゴリーの一覧
2 「test01」カテゴリー、かつfieldTest03に「ブドウ」がある一覧
IFブロックでループ内の2箇所の文言を変更 3 「test01」カテゴリーの一覧
4 「test01」カテゴリー、かつfieldTest03に「ブドウ」がある一覧
IFブロックでループごとインクルード 5 「test01」カテゴリーの一覧
6 「test01」カテゴリー、かつfieldTest03に「ブドウ」がある一覧

なお、「IFブロックでループ内の2箇所の文言を変更」というのは、変更がある2箇所の文言だけを、それぞれ条件分岐で囲んで書き換えるというものです。
テンプレートの見通しが極端に悪くなるため、私個人は使いたくありません。

・・・ <!-- BEGIN_IF [{fieldTest02}/eq/あいうえお] --><span class="acms-label acms-label-info">fieldTest02</span> {fieldTest02}<!-- ELSE_IF [{fieldTest02}/eq/かきくけこ] --><span class="acms-label acms-label-success">fieldTest02</span> {fieldTest02}<!-- ELSE_IF [{fieldTest02}/eq/さしすせそ] --><span class="acms-label acms-label-warning">fieldTest02</span> {fieldTest02}<!-- ELSE --><span class="acms-label acms-label-default">fieldTest02</span> {fieldTest02}<!-- END_IF --> ・・・


検証結果

それぞれのモジュール処理時間のPDFを添付します。

結論から言うと、5)6)は、確かにリクエストやビルドが遅くなりましたが、0.01秒程度しか差がありませんでした。全体では遅くても0.2秒だったので、ほとんど気付かなそうです。
また、ディベロッパーモードをオフにして、キャッシュも有効にするとさらに早くなります。


ファイルを開く

1)条件分岐・インクルードなし、「test01」カテゴリーの一覧


ファイルを開く

2)条件分岐・インクルードなし、「test01」カテゴリー、かつfieldTest03に「ブドウ」がある一覧


ファイルを開く

3)IFブロックでループ内の2箇所の文言を変更、「test01」カテゴリーの一覧


ファイルを開く

4)IFブロックでループ内の2箇所の文言を変更、「test01」カテゴリーでfieldTest03に「ブドウ」がある


ファイルを開く

5)IFブロックでループごとインクルード、「test01」カテゴリーの一覧


ファイルを開く

6)IFブロックでループごとインクルード、「test01」カテゴリーでfieldTest03に「ブドウ」がある

結論

以上のような結果だったので、一般的なコーポレートサイトでは、IFブロックを多めに使っても特に問題はないようです。それであれば、テンプレートの見通しの良さを優先してもいいかなと思いました。

もちろん、エントリーが数万件になることが予想される、中古車検索や不動産サイトなどは処理速度を重視した方がいいと思います。
また、今回テストに利用したエックスサーバーは、安価なレンタルサーバーの中ではスペックが高めです。メモリ等がCMSの下限ギリギリになっている爆安サーバーや、クラウドサーバーの最低構成では、この限りではないかもしれません。