先日より、WordPress で運用中のブログ(テーマは Cocoon を利用)のうちのひとつで少し気になることがありました。
それは WordPress ダッシュボード(管理画面)のツール > サイトヘルスにて「改善が必要」と表示されていたことです。
サイトヘルスの「改善が必要」には、以下の内容が提示されていました。
1件の致命的な問題
WordPress ダッシュボード サイトヘルスより文章引用
致命的な問題とは、サイトのパフォーマンスやセキュリティに多大な影響を与える可能性がある項目です。最優先で、これらの問題を解決してください。
ページキャッシュが検出されましたが、サーバーのレスポンスはまだ遅いです
パフォーマンス ページキャッシュは、ユーザーがアクセスするたびにページを読み込むのではなく、静的なページを保存して提供することで、サイトの速度とパフォーマンスを向上させます。
ページキャッシュの検出は、有効化されたページキャッシュプラグインの検索のほか、ホームページへのリクエストを3回行い、以下のHTTPクライアントキャッシュレスポンスヘッダーのうち1つ以上の検索で行います:
cache-control, expires, age, last-modified, etag, x-cache-enabled, x-cache-disabled, x-srcache-store-status, x-srcache-fetch-status.
サーバーの応答時間の中央値は775ミリ秒でした。推奨されるしきい値600ミリ秒以下の時間でなければなりません。 2個のクライアントキャッシュレスポンスヘッダーを検出しました: cache-control, expires.
この説明だけではなんとも原因が掴みにくいと思ったので、そう言う時は重たい処理を可視化するのに便利な WordPress のプラグイン「Query Monitor」をインストールして有効化します。
Query Monitor の有効化後、ブログトップページなどを表示してみると、確かにサーバーの応答時間が 0.73s(730m秒)と表示されました。
体感ではさほど遅くはないと思いつつも、ページ速度は UX や SEO 対策としては重要な要素ですし、何よりオレンジ色でワーニングが出ているのは気になります。
このサーバーの応答時間箇所をマウスオーバーするとメニューが表示され、遅いクエリーに何やら1件の表示があるのに気がつきます。
遅いクエリー (1) をクリックすると、画面下から Query Monitor の詳細が開き、内容の確認ができますが、今回の私の運営しているブログの場合ですと get_access_ranking_records() が重たい処理をしているのかな?ということが見えてきます。
続いて get_access_ranking_records() について調べてみると、WordPress テーマ Cocoon にて定められた関数であることがわかり、cocoon-master/lib/html-forms.php の generate_popular_entries_tag (人気ランキングリストの取得)で使用されていることもわかりました(該当のブログでは Cocoon の人気記事ウィジェットを利用していました)。
Cocoon の人気記事ウィジェットはアクセス集計機能を有効にして利用できる機能で、Cocoon のアクセス集計機能は WordPress ダッシュボード > Cocoon 設定 > アクセス集計 で設定が可能です。
アクセス集計設定ページでは、アクセス集計の有効化・キャッシュの有効化・キャッシュの更新間隔の設定が可能で、アクセス集計については Cocoon 公式の説明ページ(アクセス集計機能の説明: https://wp-cocoon.com/access-aggregate/ )もあります。
説明ページを読むと、サーバーに負荷がかかることや、月あたり50万PVを超えるようなサイトであればアクセス集計機能を無効にしたほうが無難であることなどが書かれていましたので、get_access_ranking_records() の処理はそれなりに重たいことも見えてきました。
今回 Query Monitor にて提示された遅いクエリーを解決するには、人気記事ウィジェットをやめる、アクセス集計を停止する、のいずれかが簡単な対策になるとは思いますが、今回のブログでは月あたり50万PVを超えるようなサイトでもないため、アクセス集計を停止せず、人気記事ウィジェットを何か別の方法で表示できないか検討することに。
そこで思いついたのが、既に導入済みの WordPress プラグイン JetPack の統計情報を利用できないかということ。
以前、Cocoon を導入していない別の WordPress サイトにて人気記事を取得したいということで、JetPack の stats_get_csv 関数を利用して統計情報から人気記事を取得するというカスタマイズを行なったことがありました。
ということで、Cocoon の HTML や CSS はそのまま活用しつつ、人気記事の取得の仕組みを JetPack に変更してみたので、そのソースコードを参考に記載します。
if ( ! function_exists('ict_yorozu_custom_stats_get_csv_add_shortcode') ) {
function ict_yorozu_custom_stats_get_csv_add_shortcode ($atts) {
$atts = shortcode_atts( array(
'days' => '30',
'limit' => '10'
), $atts, 'ict_yorozu_custom_stats_get_csv' );
$html = '';
if ( is_plugin_active('jetpack/jetpack.php') && function_exists('stats_get_csv') ) :
$top_posts = stats_get_csv( 'postviews', "days=$atts[days]&limit=$atts[limit]" );
$top_posts_count = 0;
foreach( $top_posts as $k => $v ):
if ( $v['post_id'] !== '0' && $top_posts_count < 5 ) :
$top_posts_count++;
$no_thumbnail_url = get_no_image_120x68_url($v['post_id']);
$post_thumbnail = get_the_post_thumbnail( $v['post_id'], 'thumb', array('alt' => '') );
if ($post_thumbnail) {
$post_thumbnail_img = $post_thumbnail;
} else {
$post_thumbnail_img = get_original_image_tag($no_thumbnail_url, $w, $h, 'no-image popular-entry-card-thumb-no-image widget-entry-card-thumb-no-image', '');
}
$html .= '<a href="' . esc_url( get_permalink( $v['post_id'] ) ) . '" class="popular-entry-card-link a-wrap no-' . $top_posts_count . '" title="' . esc_attr( get_the_title( $v['post_id'] ) ) . '">';
$html .= '<div class="popular-entry-card widget-entry-card e-card cf">';
$html .= '<figure class="popular-entry-card-thumb widget-entry-card-thumb card-thumb">';
$html .= $post_thumbnail_img;
$html .= '</figure><!-- /.popular-entry-card-thumb -->';
$html .= '<div class="popular-entry-card-content widget-entry-card-content card-content">';
$html .= '<span class="popular-entry-card-title widget-entry-card-title card-title">' . esc_html( get_the_title( $v['post_id'] ) ) . '</span>';
$html .= '</div><!-- /.popular-entry-content -->';
$html .= '</div><!-- /.popular-entry-card -->';
$html .= '</a><!-- /.popular-entry-card-link -->';
endif; // $v['post_id'] !== '0' && $top_posts_count < 5
endforeach; // $top_posts as $k => $v
else:
$html .= __('Jetpack Plugin Not Working.', 'cocoon-child');
endif; // is_plugin_active('jetpack/jetpack.php') && function_exists('stats_get_csv')
return $html;
}
add_shortcode( 'ict_yorozu_custom_stats_get_csv', 'ict_yorozu_custom_stats_get_csv_add_shortcode' );
}
上記ソースコードを functions.php に記載しサーバーに反映後、表示したい箇所のウィジェット等にショートコード [ict_yorozu_custom_stats_get_csv] を貼り付けると、Cocoon の CSSはそのままで JetPack の統計情報から人気記事を取得できるようになります。
JetPack の関数 stats_get_csv に渡す limit(取得する記事数)を 10 と指定している箇所がありますが、トップページやアーカイブページが人気記事に含まれる場合がありますので、それを考慮して少し多めに取得しています。
上記コードを実行すると、実際には5件の人気記事が出力される形です。
$html に格納している HTML 要素は cocoon-master/lib/html-forms.php の generate_popular_entries_tag を参考に必要な HTML要素を入れています。
このソースコードに変更後、改めて Query Monitor を確認してみると、サーバーの応答時間は 0.45s(450ms)と速度が速くなり、遅いクエリー (1) は消えました。
また、WordPress のサイトヘルスを確認してみると、結果は良好と表示されるようになりました。
WordPress のサイトヘルスで改善が必要と表示される原因は環境により様々ですが、Query Monitor を有効化し見える化することで解決に至ったのはよかったことと思います。
また、今後サイトを運営していく中で、アクセスが増えるようだったら Cocoon のアクセス集計機能はオフにするなど対策が必要なことも理解するきっかけとなりよかったなと思います。
参考情報
アクセス集計機能の説明 | Cocoon
コメント