【WordPress】「永続オブジェクトキャッシュを使用してください」が気になったのでコアを覗いてみた

はじめに

WordPress 6.1から、サイトヘルスステータスにて永続オブジェクトキャッシュの使用がレコメンドされるようになったようです。

永続オブジェクトキャッシュを使用してくださいという、サイトヘルスステータスの結果が記載されています

こちらの対応としては、ホスティングプロバイダーが提供するキャッシュサーバーを確認し、 W3 Total Cache Plugin などのキャッシュ系プラグインを介してオブジェクトキャッシュを使用する設定を行う、ということになるようです。
https://ja.wordpress.org/support/article/optimization/#persistent-object-cache

気になったので、今回はサイトヘルスステータスで何をチェックしているかを見ていきます。

※オブジェクトキャッシュが何をしているか、というところまでは言及しません。

コードを読む

コアコードを読む

サイトヘルスステータスでテストする項目は WP_Site_Health::get_tests で列挙されています。
6.1から追加されたのは、 persistent_object_cache というテストです。

$tests['direct']['persistent_object_cache'] = array(
    'label' => __( 'Persistent object cache' ),
    'test'  => 'persistent_object_cache',
);

ここに列挙されているテストは get_test_ というprefixがついたfunctionとして用意されており、サイトヘルスステータスの画面を開くたびに実行されます。
今回の場合だと、 get_test_persistent_object_cache というfunctionになります。

/**
 * Tests if the site uses persistent object cache and recommends to use it if not.
 *
 * @since 6.1.0
 *
 * @return array The test result.
 */
public function get_test_persistent_object_cache() {
(省略)
    if ( wp_using_ext_object_cache() ) {
        return $result;
    }
(省略)
    return $result;
}

どうやらこのfunction内で呼び出している wp_using_ext_object_cache というfunctionでオブジェクトキャッシュの判定を行っているようです。

/**
 * Toggle `$_wp_using_ext_object_cache` on and off without directly
 * touching global.
 *
 * @since 3.7.0
 *
 * @global bool $_wp_using_ext_object_cache
 *
 * @param bool $using Whether external object cache is being used.
 * @return bool The current 'using' setting.
 */
function wp_using_ext_object_cache( $using = null ) {
	global $_wp_using_ext_object_cache;
	$current_using = $_wp_using_ext_object_cache;
	if ( null !== $using ) {
		$_wp_using_ext_object_cache = $using;
	}
	return $current_using;
}

ここでは、globalの $_wp_using_ext_object_cache が初期化されているかどうかを判定しています。
初期化処理は load.phpwp_start_object_cache というfunction内で行っています。

/**
 * Start the WordPress object cache.
 *
 * If an object-cache.php file exists in the wp-content directory,
 * it uses that drop-in as an external object cache.
 *
 * @since 3.0.0
 * @access private
 *
 * @global array $wp_filter Stores all of the filters.
 */
function wp_start_object_cache() {
	global $wp_filter;
	static $first_init = true;

	// Only perform the following checks once.

	/**
	 * Filters whether to enable loading of the object-cache.php drop-in.
	 *
	 * This filter runs before it can be used by plugins. It is designed for non-web
	 * runtimes. If false is returned, object-cache.php will never be loaded.
	 *
	 * @since 5.8.0
	 *
	 * @param bool $enable_object_cache Whether to enable loading object-cache.php (if present).
	 *                                  Default true.
	 */
	if ( $first_init && apply_filters( 'enable_loading_object_cache_dropin', true ) ) {
		if ( ! function_exists( 'wp_cache_init' ) ) {
			/*
			 * This is the normal situation. First-run of this function. No
			 * caching backend has been loaded.
			 *
			 * We try to load a custom caching backend, and then, if it
			 * results in a wp_cache_init() function existing, we note
			 * that an external object cache is being used.
			 */
			if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
				require_once WP_CONTENT_DIR . '/object-cache.php';
				if ( function_exists( 'wp_cache_init' ) ) {
					wp_using_ext_object_cache( true );
				}
(省略)
}

wp_cache_initcache.php 内で定義されていますが、この時点では読み込まれていません。
wp-content 配下に object-cache.php が存在する場合は読み込む、(その中で) wp_cache_init が定義されていれば、wp_using_ext_object_cache にtrueを渡し、$_wp_using_ext_object_cache をtrueで初期化する、という流れになっています。

プラグインのコードを読む

ということで、この object-cache.php が肝であることがわかったのですが、このファイルはコアコードには存在しません。
ではどこに存在するかというと、オブジェクトキャッシュを提供する各プラグイン内のようです。

以下は W3 Total Cache Plugin を有効化すると生成される object-cache.php です。
この中で wp_cache_init が定義されています。

/**
 * Init cache
 *
 * @return void
 */
function wp_cache_init() {
    $GLOBALS['wp_object_cache'] =
        \W3TC\Dispatcher::component( 'ObjectCache_WpObjectCache' );
}

リファレンスにもある通り、、オブジェクトキャッシュ提供するプラグインをインストールしない限りオブジェクトキャッシュは非永続であるとのことだそうです。

By default, the object cache is non-persistent. This means that data stored in the cache resides in memory only and only for the duration of the request. Cached data will not be stored persistently across page loads unless you install a persistent caching plugin.

https://developer.wordpress.org/reference/classes/wp_object_cache/

おわりに

サイトヘルスステータスでは、オブジェクトキャッシュのプラグインを利用しているかどうかをチェックして永続オブジェクトキャッシュの利用を判定していました。
そもそも永続オブジェクトキャッシュはWordPress標準では提供しておらず、利用したければプラグインをインストールすること、そしてそれを推奨しているようです(ver 6.1以降)。
言い換えると、オブジェクトキャッシュ自体は抽象化されおり、各ホスティングプロバイダーの都合によって独自実装する余地を残しているとも言えるかと思います。

タイトルとURLをコピーしました