parudou
parudou
parudou
更新日:2018/10/15

ワードプレスのランダム表示の負荷を軽くする方法(キャッシュとか)

ワードプレスのクエリーで重たい処理といえば「記事のランダム表示」。
「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で自動的にキャッシュ作成するのも良いと思います。

是非ご感想・ご指摘等をください。

プロフィール

管理人:parudou
単なるWEBサイト作成マニアです。
底辺法人アフィリエイター。
Twitterはこちら

日記はパルどうSEOブログ

Copyright (c) parudou All Rights Reserved.