MENU CLOSE

【WordPress】
Transients APIを使って
データをキャッシュする方法

Transients API
Transients API

Transients APIとは

WordPressで使える簡易なキャッシュ機能で、有効期限付きでデータをDB(wp_optionsテーブル)に一時保存できます。キャッシュの作成も破棄も簡単な関数で制御できます。WP_Queryで複雑な条件を指定して取得するような重めのデータや、ある程度の期間内容が変わらないようなWeb APIから取得するデータなどをキャッシュしておくと、アクセスするたびに発生するDBやAPIへのリクエストを減らすことができ、無駄なアクセスやサーバー負荷を抑えることが可能です。

Transients API

https://wpdocs.osdn.jp/Transients_API

Transients APIの使い方

特に内部的に自動で使えるようになっているわけではないので、使いたい場所でコードを書いて使います。
WordPressの関数として用意されているので使い方はとてもシンプルです。

キャッシュの作成

<?php set_transient( $transient, $value, $expiration ); ?>
  • $transient
    キャッシュの名前。長さ45 文字以下の制限あり。キャッシュを使う時、破棄する時に使います。
  • $value
    キャッシュするデータ。単純な文字列や数値はもちろん、配列やオブジェクトもキャッシュできます。
  • $expiration
    キャッシュが切れるまでの秒数。0は無期限。この期間を過ぎるとキャッシュは自動的に破棄されます。

関数リファレンス/set transient

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/set_transient

キャッシュの取得

<?php get_transient( $transient ); ?>
  • $transient
    set_transientで指定したキャッシュの名前。

戻り値にキャッシュしたデータが返ってきます。
キャッシュが存在しないか、データがない、もしくは有効期限が切れている場合はfalseを返します。

<?php
//戻り値を変数に入れる
$transients = get_transient( 'transients_data' );

//空判定
if( !empty($transients) ){
  // キャッシュがある時の処理
}
?>

実際のコードではこんな感じで使うことになります。

関数リファレンス/get transient

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/get_transient

キャッシュの削除

<?php delete_transient( $transient ); ?>
  • $transient
    set_transientで指定したキャッシュの名前。

関数リファレンス/delete transient

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/delete_transient

また、ダッシュボードからボタン一つでTransientを全てクリアするプラグイン「Clear Transient From Dashboard」というものもあります。

とにかく全部一括で消して確認したいっていう場合にはこちらのプラグインがおすすめです。

その他の関数

set site transientget_site_transientdelete_site_transientというsite_がついた関数があります。似た様な名前の関数なのですが、同じのデータを扱えるわけではありません。これらはWordPressをマルチサイトとして使うときにネットワーク全体で共通で使えるようになるものです。

<?php 
//データをキャッシュ
set_transient( 'transient_data', 1, 60 * 60 * 24);
set_site_transient( 'transient_data', 2, 60 * 60 * 24);

//キャッシュを取得
get_transient( 'transient_data' ); // 1
get_site_transient( 'transient_data' ); // 2
?>

このようにsite_が付いているかついていないかで扱いが違ってきます。
マルチサイトはデメリットがあるので、かなり特殊な事情がないと選択しない手法ですし、その上サイトを跨いでキャッシュを使うことなんてまぁないです。

通常はsite_のついていないTransientを使っておけば問題ありません。

WP_Queryをキャッシュしてみる

Transients APIを使ってWP_Queryで取得したデータをキャッシュしてみます。

<?php
$transient_name = 'new_post_list';
$query = get_transient($transient_name); //もしキャッシュがあれば利用
if(empty($query)){
  $args = [
    'post_type'              => 'post',
    'posts_per_page'         => -1,
    'orderby'                => 'date'
  ];
  $query = new WP_Query( $args );
  //ログインユーザーはキャッシュしない
  if(!is_user_logged_in()){
    set_transient( $transient_name, $query, 60 * 60 * 24 );
  }
}

if ( !empty($query) && $query->have_posts() ):
  while ( $query->have_posts() ) :
    $query->the_post();

    //ループの内容

  endwhile;
  wp_reset_postdata();
endif;

このようにしておくと、ページを表示するたびにWP_Queryの引数によって内部的に実行していた複雑なSQLを省略して、キャッシュしたデータを扱うことができます。

ここではサンプルコードなので、新着記事10記事のキャッシュですが、meta_queryパラメータを使ってカスタムフィールドの値を条件にしたり、date_queryパラメータを使って日時を条件に加えたりとパラメータによって条件が複雑になることで負荷が増し、重くなることもあります。

そういった時に上記のコードのようにTransient APIでキャッシュしておくとかなりの負荷を削減できます。

記事の更新時にキャッシュを消す

上記でキャッシュはうまくいくのですが、このままでは有効期限の1日が経過するまでの間、ずっとキャッシュを参照してしまい、その間に記事を公開したり削除したりしても反映されません。

つまり記事の公開・更新・削除のタイミングでキャッシュのクリアが必要になります。
具体的には下記のようにアクションフックを利用してTransientを破棄します。

functions.php

function clear_transient_cache() {
  delete_transient('new_post_list');
}
add_action( 'publish_post', 'clear_transient_cache');
add_action( 'deleted_post', 'clear_transient_cache');
add_action( 'save_post', 'clear_transient_cache');
add_action( 'edit_post', 'clear_transient_cache');

こうしておくことで、記事の更新のタイミングでキャッシュが破棄され、次にページを表示した時は新しいキャッシュに置き換わります。

キャッシュを扱う時の注意点

なんでもかんでもWP_QueryをTransientでキャッシュすればええやん!って思う方がいるかもしれませんので、注意点を書いておきます。先ほどのコードを使って説明します。

<?php
$transient_name = 'new_post_list';
$query = get_transient($transient_name); //もしキャッシュがあれば利用
if(empty($query)){
  $args = [
    'post_type'              => 'post',
    'posts_per_page'         => -1,
    'orderby'                => 'date'
  ];
  $query = new WP_Query( $args );
  //ログインユーザーはキャッシュしない
  if(!is_user_logged_in()){
    set_transient( $transient_name, $query, 60 * 60 * 24 );
  }
}

if ( !empty($query) && $query->have_posts() ):
  while ( $query->have_posts() ) :
    $query->the_post();

    //ループの内容

  endwhile;
  wp_reset_postdata();
endif;

ここでTransientを使う際にはポイントがあります。
コメントにある通り、is_user_logged_in関数で条件判定し、WPにログインしているユーザーはキャッシュしないようにしておくことです。

理由は、例えば非公開記事として記事を書いて、その記事はログインユーザーだけが見れるようになっている場合、そのままキャッシュされてしまったらログインユーザー以外にも非公開記事が表示されてしまいます。それは非常にまずいですよね。

ここではログインユーザーはキャッシュの対象に含まないようにして防止しましたが、そもそもキャッシュを使うべきではないような場面もあります。

  • ログイン/ログアウトで内容が変わるデータ
  • ランダム表示のデータ
  • 現在時間と比較して表示するようなデータ

こういうものはキャッシュと相性が悪いので、キャッシュを使わない方が良いでしょう。
どうしても取り入れたい時は、本当に必要かどうか、キャッシュの作成と破棄がちゃんとできる設計になっているか、しっかり検討しましょう。

おわりに

今回はTransient APIについてメモしました。
WPですぐに使えるWP_Queryを例にしましたが、WP内であればどこでも使えるので、他にもカテゴリーやタグ一覧をキャッシュしたり、郵便番号や祝日のデータなど、WebAPIから引っ張ってきて何か処理する場合に、直接アクセスせずにREST APIを噛ませてWPにキャッシュしておいたものを処理したり、などなど使い方は様々です。

ただ、あくまで一時的なデータ保存として使うことを主目的とすることが大事です。そのためTransientとして扱うデータは、有効期限が切れたら再取得できるものに限ります。

そこさえ守れば、いろいろと使えて開発が捗る便利なAPIだと思います。
他の使い方を知りたい場合は、いろんなプラグインの中身を見てみると、けっこう使われていることが多いので参考になります。

記事一覧

RELATED

Swiper v6 → v7
inoue
inoue
TIPS

Swiper(v7)へのアップグレード対応

WordPress add_rewrite_rule
inoue
inoue
TIPS

【WordPress】add_rewrite_ruleでリライトルールを追加する

PhotoSwipe
inoue
inoue
TIPS

PhotoSwipeを使って画像をポップアップ表示する【Swiper(v7)との連携あり】

Flatpickr
inoue
inoue
TIPS

Flatpickrで日時入力をカレンダー表示にする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【実践編】見出しの文言を変更できるようにする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【デザインオプション編】テーマに新しい機能を加える方法

NEW POSTS

Dart Sass + Gulp
inoue
inoue
TRY

DartSassがなかなか辛かったのでGulpを修正してみた

svg-audiovisualizerAudioVisualizer [ howler.js + SVG ]
inoue
inoue
TRY

【howler.js】ストリーミング音源からオーディオビジュアライザーを作る

Simple GA Ranking
inoue
inoue
TRY

Simple GA Ranking[ver2.1.6]が表示されないので調べてみた

Sass @import → @use
inoue
inoue
TRY

【Sass】@importを@useに置き換えてみる《FLOCSS対応》

Stripe Payment Links
inoue
inoue
TRY

コーディング一切不要のStripe Payment Linksで決済機能を試してみる

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【準備編】カスタマイズに必要な前提知識について

ブログ記事一覧
  • HOME
  • TIPS
  • 【WordPress】Transients APIを使ってデータをキャッシュする方法