FSEの導入が本格化すると、Wordpressのウィジェットエリアは残っても、ウィジェットは消え去りそうな雰囲気がある今日この頃。
クエリを走らせるタイプのウィジェットは、記事の数が増えるとページの読み込みが遅くなる原因になります。
テーマによってはサイドバーやフッターなどを丸ごとキャッシュできるテーマもありますが、そういうテーマを使ってない人も多いでしょう。
SWELLにはサイドバーをキャッシュする機能があります。
SWELLは、サイドバー出力を全部キャッシュするか、しないかの2択になっており、個別のウィジェット出力をキャッシュする機能はありません。
ウィジェットの出力が動的に変化しないのであれば、ウィジェットの出力をキャッシュする方が速くなるはずです。
ウィジェットの出力をどうやってキャッシュするのか調べてみたら、結構簡単な仕組みで出来ることがわかりました。
Widget Output cacheというプラグインがある
特定のウィジェットだけキャッシュしたかったのでプラグインを使うのはどうかと思ったのですが、Widget Output cacheというプラグインがそのものずばりでした。
更新は止まっているのですが、まだ公式からインストールできます。

このプラグインは、有効化すると基本全てのウィジェットがキャッシュされます。
キャッシュしたくない場合は、各ウィジェットの設定から除外指定するという仕組みです。
キャッシュをするウィジェットが少ない、例えば1個だとすると、設定する量が多くてうまくないです。
キャッシュ除外⇒有効化にフラグを変更してみる
プラグインのソースを見ると、ファイルは1つで中身はシンプルです。
自分でも管理できそうなので、プラグインのソースを変更して、自分好みの動きに変更してみました。
- 初期状態ではウィジェット出力をキャッシュしない
- ウィジェットのオプションから個別に有効化
ソースの必要なところだけ変更して、プラグインのバージョンの数値を上げておけばアップデートの通知もきません。
if ( in_array( $widget_object->id, $this->excluded_ids ) == false) // 変更
return $instance;
printf(
'<p>
<label>
<input type="checkbox" name="widget-cache-exclude" value="%s" %s />
%s
</label>
</p>',
esc_attr( $object->id ),
checked( $is_excluded, true, false ),
esc_html__( 'キャッシュする' ) // 変更
);
変更したのは2行だけです。
excludeする判定部分とウィジェットのチェックボックスの表記を変更しました。
Widget出力をキャッシュする仕組み
プラグインのソースを見ると、widget出力をキャッシュする仕組みが理解できます。
widget出力時に呼び出されるcallbackをフックで登録して、transientでキャッシュしています。
プラグインを使わなくても、この部分だけでキャッシュはできますが、個別のwidgetの指定が面倒なのでチェックボックスを使えるプラグインの方が便利だと思います。
// Overwrite widget callback to cache the output
add_filter( 'widget_display_callback', array( $this, 'widget_callback' ), 10, 3 );
function widget_callback( $instance, $widget_object, $args ) {
// Don't return the widget
if ( false === $instance || ! is_subclass_of( $widget_object, 'WP_Widget' ) )
return $instance;
if ( in_array( $widget_object->id, $this->excluded_ids ) == false)
return $instance;
$timer_start = microtime(true);
$cache_key = sprintf(
'cwdgt-%s',
md5( $widget_object->id . get_option( 'cache-widgets-version', 1 ) )
);
$cached_widget = get_transient( $cache_key );
if ( empty( $cached_widget ) ) {
ob_start();
$widget_object->widget( $args, $instance );
$cached_widget = ob_get_contents();
ob_end_clean();
set_transient(
$cache_key,
$cached_widget,
apply_filters( 'widget_output_cache_ttl', 60 * 60 * 24 * 7, $args )
);
printf(
'%s <!-- Stored in widget cache in %s seconds (%s) -->',
$cached_widget,
round( microtime(true) - $timer_start, 4 ),
$cache_key
);
} else {
printf(
'%s <!-- From widget cache in %s seconds (%s) -->',
$cached_widget,
round( microtime(true) - $timer_start, 4 ),
$cache_key
);
}
// We already echoed the widget, so return false
return false;
}
まとめ
ウィジェット出力は、ページキャッシュプラグインがあれば不要だとおもいますが、ページキャッシュプラグインを入れない場合は、特殊な事情がある人はウィジェット出力をキャッシュする簡単な仕組みがあることを覚えておいた方が良いと思います。