PowerCMS X ブログ

2022-06-07

ビュー (テンプレート) の記述方法による再構築の軽量化について

PowerCMS Xは、再構築の高速処理を大きな特長の一つとしていますが、データベースのレコードが増えていくにつれて、またビュー (テンプレート) の記述が複雑になっていくにつれ、静的生成・動的生成ともにビューのビルドに時間がかかってくることは従来と変わりません。この記事では、PowerCMS Xならではのビューの記述方法による再構築の軽量化についてのヒントをご紹介します。

計測する

まずは、ページの中のどの部分の処理に時間がかかっているかを計測します。mt:speedmeterブロックタグを使うと便利です。時間がかかっていると思われるオブジェクトのループやループの中でループが呼ばれているなどの部分にあたりを付け、タグで囲ってください。

<mt:speedmeter name="ブロックの名前">
〜
</mt:speedmeter>

このブロックが処理されると、出力ソースの中に以下のHTMLコメントが追加されます。

<!--ブロックの名前 start.-->
〜
<!--ブロックの名前 took 0.7436 seconds to process this block.-->

ブロックは1つのビューに複数指定できますので、部分部分に埋め込んでください。HTMLコメントなので、HTMLで表示するときには影響ないと思われますが、公開中のページにコメントを出力されたくない場合は、プレビューなどでも確認できます。

ループタグの属性指定による利用するカラムの指定

PowerCMS Xでオブジェクトをループ出力するブロックタグ (例 : mt:entries, mt:pages)、リレーション指定されているオブジェクトを出力するブロックタグ (例 : mt:entrycategories, mt:entrytags ) に指定できるタグ属性「cols」を指定します。この属性は、ブロック内で利用されるカラムを絞り込む目的で指定します。

記事のループの指定の例

例えば、記事タイトルと公開日、パーマリンクのみを出力するループでは、以下のように指定します。指定はカンマ区切りテキストか、配列です。

<mt:entries cols="title,published_on">
〜
</mt:entries>

リレーション型、バイナリ型のカラムは指定の必要はありません。このループタグが呼ばれた時に発行されるSQL文は下記となります。

SELECT entry_title,entry_published_on FROM mt_entry ...

※ 実際には以下のカラムは自動的に指定されますが、すべてのカラムを無条件に読み込むことによるオブジェクトの肥大化を避け、軽量・高速に動作させることができます。特に、カラムを多数作成しているモデルでその差は顕著です。

  • id
  • workspace_id
  • status
  • basename

mathタグの代わりに opモディファイアを利用する

ver.2.58より「opモディファイア」が利用可能になりました。テンプレートタグで四則計算が可能になる、という点ではファンクション・タグ「mt:math」と同じですが、opモディファイアのほうがより高速です。また、単純な加算・減算の場合は「incriment」「decriment」モディファイアが利用でき、こちらも mt:mathタグより高速です。

モジュールをキャッシュする

ビューの共通部分を別のモジュールにして mt:includeタグでインクルードしている時、cache_key属性にユニークなキーを渡すことで、モジュールのビルド結果がキャッシュされます。このキャッシュはメモリにキャッシュされ(永続的に保存されず)、index.phpへのリクエストが終わると自動的に破棄されます。ポップアップウィンドウからの再構築時には、一連のリダイレクトが完了するまで保持され、完了すると自動的に破棄されます。

<mt:include module="(Website) HTML Footer" cache_key="ユニークなキャッシュのキー">

ブロック単位でのキャッシュ

モジュールのキャッシュと同様にブロック単位でキャッシュすることができます。以下の指定では、モジュールのキャッシュと同様にメモリにキャッシュされ、index.phpへのリクエスト終了またはポップアップウィンドウからの再構築時には、一連のリダイレクトが完了するまで保持され、完了すると自動的に破棄されます。

<mt:cacheblock cache_key="ユニークなキャッシュのキー">
〜
</mt:cacheblock>

ダイナミックパブリッシング時のキャッシュへの追加属性

ダイナミックパブリッシング (動的生成) ではメモリに保存されたキャッシュは常にリクエストごとに生成・破棄されるため、モジュールやブロックのキャッシュは意味をなしません。以下の属性を追加で指定することができます。以下のブロックは、記事とページの更新があると破棄され、そうでない場合、最大1日キャッシュされます。これらの属性は、mt:includeタグ、mt:cacheblockタグ共通です。

<mt:cacheblock cache_key="ユニークなキャッシュのキー" workspace_id="スペースのID" triggers="entry,page" cache_ttl="86400">
〜
</mt:cacheblock>

以下のブロックは、記事IDが「1」の記事の更新があると破棄され、そうでない場合、最大1日キャッシュされます。

<mt:cacheblock cache_key="ユニークなキャッシュのキー" workspace_id="スペースのID" triggers="entry" cache_object_id="1" cache_ttl="86400">
〜
</mt:cacheblock>

DynamicCachingプラグインの利用

ダイナミックパブリッシング (動的生成) ではページを丸ごとキャッシュさせることができます。キャッシュは再構築トリガーの設定によって破棄され、Membersプラグインにより会員ユーザーがログインして閲覧する場合はキャッシュされません。

共通部分を静的ファイル化してインクルードするか、非同期読み込みする

こちらは静的生成・動的生成共通となります。例えば以下の記事で紹介している「やさにちウォッチ 別ウィンドウで開きます」でランキングを表示させている部分ですが、全てのページで共通であり、1日に1回更新されればよい部分となっています。

このような部分については、静的にインデックス・アーカイブを出力して、mt:includeタグでファイルをインクルードするようにするか、JSON形式で静的ファイルを出力するようなビューを作成して、Ajaxリクエストなどで非同期に読み込むことで、負荷を軽減でき、ページ表示速度も速くすることができます。

DBのチューニングや再構築の並列処理などの選択肢

ループのフィルタに利用しているカラムには「インデックス」を指定する

ループのタグでリレーション(記事に対するカテゴリやタグ)以外の、モデルの標準カラムでフィルタリングして出力する時は、そのカラムに「インデックス」を指定することで高速化するいことができます。以下の例では、記事に「filter」というカラムを追加して、その値でフィルタリングしている例です。

<mt:entries filter="値">
〜
</mt:entries>

この記事ではビュー (テンプレート) に絞ってご紹介したため、その他の高速化手法については改めて纏めてご紹介します。

ブログ内検索

アーカイブ