ワードプレスのランダム表示の負荷を軽くする方法(キャッシュとか)
ワードプレスのクエリーで重たい処理といえば「記事のランダム表示」。
「ORDER BY RAND」のクエリーはとにかく重い。
軽くするコツを2つ紹介します
コツ1:ランダム取得は一度のみ
例えば、次のようにランダム記事を表示したいとします。
この場合、初心者だと次のようなソースを書くはずです。
<?php
//記事上の部分
$args = array(
'posts_per_page' => 5,
'orderby' => 'rand',
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$thumpass = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail');
?>
<a href="<?php the_permalink() ?>">
<img src="<?php echo $thumpass[0] ?>" alt="" />
<?php the_title(); ?>
</a>
<?php
endwhile;
endif;
wp_reset_postdata();
?>
<?php
//記事本文の部分
if (have_posts()) :
while (have_posts()) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; endif; ?>
<?php
//記事下の部分
$args = array(
'posts_per_page' => 10,
'orderby' => 'rand',
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$thumpass = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail');
?>
<a href="<?php the_permalink() ?>">
<img src="<?php echo $thumpass[0] ?>" alt="" />
<?php the_title(); ?>
</a>
<?php
endwhile;
endif;
wp_reset_postdata();
?>
これだとランダム表示のクエリーを2回も発行することになります。
これを1回のみにしたい。
記事数が少ない場合は2回でも気になりませんが、
1000記事レベルになると、明らかに重いと感じます。
だから、1回を死守。
次のコードをheader.phpに書きます。
※どのページでも読み込まれるファイルに書く。
別ファイルに書き、それをインクルードしてもOK。
<?php
//ランダム記事をまとめて取得
//記事・固定ページでは現在の記事は除外(一応)
if( is_singular() ){
$args = array(
'posts_per_page' => 15,
'post__not_in' => array($post->ID),
'orderby' => 'rand',
);
}else{
$args = array(
'posts_per_page' => 15,
'orderby' => 'rand',
);
}
$the_query = new WP_Query($args);
//変数を配列として宣言
//globalしないと他のテンプレで使えない
global $kijidata;
$kijidata = array();
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$thumpass = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail');
//取得した記事を変数(配列)に格納
$kijidata[] = array("title" => $post->post_title,"url" => get_permalink($post->ID),"img" => $thumpass[0]);
endwhile;
endif;
wp_reset_postdata();
?>
次にランダム記事を表示したい箇所に次のようにコードを追加します。
(index.php、single.phpなど、どこでもいい)
<?php
//記事上
global $kijidata;
//配列の0~4を取り出す(5記事取得)
for ($i = 0; $i < 5; $i++){ ?>
<a href="<?php echo $kijidata[$i]["url"]; ?>">
<img src="<?php echo $kijidata[$i]["img"]; ?>" alt="" />
<?php echo $kijidata[$i]["title"]; ?></a>
<?php } ?>
<?php
//記事下
global $kijidata;
//配列の5~14を取り出す(10記事取得)
for ($i = 5; $i < 15; $i++){ ?>
<a href="<?php echo $kijidata[$i]["url"]; ?>">
<img src="<?php echo $kijidata[$i]["img"]; ?>" alt="" />
<?php echo $kijidata[$i]["title"]; ?></a>
<?php } ?>
HTMLタグ、CSSは各自追加ください。
最初に15記事分を変数にて取得しておき、
その変数を使って表示する仕組みです。
こうすることで自由にランダム記事を表示でき、かつ重複も無い。
ランダム表示のクエリーはこのようにして、必ず一度だけにしよう。
コツ2:キャッシュする
常にランダムでなくても良いのなら、キャッシュするのが基本。
なぜランダム表示をするのか?の目的によりますが、
ユーザーにいろいろな記事を見せたいなら、30秒に1度程度の更新で十分だろう。
ということで、キャッシュの設定を紹介します。
まず、次の名前の空ファイルを直下のディレクトリに保存します。
(wp-config.phpなどがあるディレクトリ)
randomcache.txt
パーミッションは「600」に設定してください。
PHPでやってもいいのですが、無駄な処理が増えるので、ここは手動。
では、ソースを。
<?php
//キャッシュファイル名を指定
$randomcache = "randomcache.txt";
//キャッシュファイルの更新日を取得。
$writetime = filemtime($randomcache);
//キャッシュする時間(秒)を指定。
$cachetime = 30;
//前回のキャッシュから設定した時間以上経過している場合
if(($writetime + $cachetime) < time() ){
//ランダム記事を新規に取得します。
if( is_singular() ){
$args = array(
'posts_per_page' => 15,
'post__not_in' => array($post->ID),
'orderby' => 'rand',
);
}else{
$args = array(
'posts_per_page' => 15,
'orderby' => 'rand',
);
}
$the_query = new WP_Query($args);
//変数を配列として宣言
$kijidata = array();
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$thumpass = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'thumbnail');
//取得した記事を変数(配列)に格納
$kijidata[] = array("title" => $post->post_title,"url" => get_permalink($post->ID),"img" => $thumpass[0]);
endwhile;
endif;
wp_reset_postdata();
//取得した記事をキャッシュファイルに保存
file_put_contents($randomcache, serialize($kijidata));
}
//キャッシュファイルからデータを取得
global $randomkiji;
$randomkiji = unserialize(file_get_contents($randomcache));
?>
次にランダム記事を表示したい箇所に次のようにコードを追加します。
(index.php、single.phpなど、どこでもいい)
<?php
//配列の0~4を取り出す(5記事分
global $randomkiji;
for ($i = 0; $i < 5; $i++){ ?>
<a href="<?php echo $randomkiji[$i]["url"]; ?>">
<img src="<?php echo $randomkiji[$i]["img"]; ?>" alt="" />
<?php echo $randomkiji[$i]["title"]; ?></a>
<?php
}
?>
30秒後に誰かがアクセスしたら、ランダム表示が変わるようになります。
こうしてキャッシュすると、同時アクセスにとても強くなります。
サイトによっては1日でも1年でもいいでしょう。
ランダム表示だけでなく、クエリー全てをこうしてキャッシュできますので、
キャッシュプラグインを使用せず負荷を削減したいのであれば、
いろいろ工夫してみてください。
cronで自動的にキャッシュ作成するのも良いと思います。
ツイート是非ご感想・ご指摘等をください。