ワードプレスは記事データのキャッシュが必須!という話
ワードプレスはとにかく軽くする
ベテランほど軽さを重視するだろう。
良いサーバーも大事ですが、軽くすることの方が大事です。
このあたりの話を。
1、なぜ軽くしないといけないのか?
アクセス集中に耐えられないからです。
普段のポツポツしたアクセスならば何ら問題は無いのですが、
1秒間に100人!とかになった場合に軽くないとダウンします。
ここを想定して設計しないといけない。
話題になった企業サイトなんかはすぐ落ちているのが、
このアクセス集中を想定していないためです。
デザインばっかりでこの一番大事なところを考えていない人が多いよう思える。
ワードプレスも重たいシステムなので、対策しないとダメ。
静的キャッシュが最強ですが、そこまでしなくてもいける。
そこの話をしたい。
2、とにかくDBにアクセスさせない
記事をDBから取得するのは最小限にする。
ワードプレスが重たい理由はDBへのアクセスにあります。
「WP_Query」での記事取得なんかは本当重たいです。
メモリもたくさん使ってしまい、サーバーダウンの要因に。
したがって、メイン記事だけはDBから取得し、
「記事一覧」や「関連記事」はキャッシュから取得します。
3、ダメな例(WP_Query)
<?php
$args = array(
'posts_per_page' => 10,
'cat' => $cat_id,
'post__not_in' => array($post->ID),
);
}
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
~
<?php
endwhile;
endif;
wp_reset_postdata();
?>
「WP_Query」で記事を取得する最も一般的な方法ですが、
重たいので基本的には使わない方がいい。
サブクエリは使わず、メインクエリーだけにしよう。
4、良い例(キャッシュ)
※キャッシュ専用phpを作って都度実行する
<?php
$dirpath = $_SERVER['DOCUMENT_ROOT'];
$args = array(
'posts_per_page' => -1,
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$postid = get_the_ID();
$title = get_the_title();
$permalink = get_permalink();
$text = strip_tags(get_the_content());
$subject = array(
''
);
$pattern = array(
'#\[.+?\]#'
);
$text = preg_replace($pattern, $subject, $text);
$text = mb_strimwidth($text,0,140,'…', 'UTF-8');
$text = preg_replace('/\r\n|\n|\r/', '', $text);
$text = esc_attr($text);
$posted_date = get_the_time('Y/m/d');
$eyecatch_medium_large = wp_get_attachment_image_src(get_post_thumbnail_id($postid), 'medium_large');
$eyecatch_full = wp_get_attachment_image_src(get_post_thumbnail_id($postid), 'full');
$category = get_the_category();
$cat_id = $category[0]->cat_ID;
$cat_name = $category[0]->cat_name;
$cat_slug = $category[0]->category_nicename;
$the_modified_date1 = get_the_modified_date('c');
$the_modified_date2 = get_the_modified_date('Y/m/d');
$datePublished = get_the_time('c');
$prevpost = get_adjacent_post(true, '', true); //前の記事
$nextpost = get_adjacent_post(true, '', false); //次の記事
if( $prevpost or $nextpost ){
if ( $nextpost ) {
$nextpost_id = get_permalink($nextpost->ID);
$nextpost_title = get_the_title($nextpost->ID);
}else{
$nextpost_id = "";
$nextpost_title = "";
}
if ( $prevpost ) {
$prevpost_id = get_permalink($prevpost->ID);
$prevpost_title = get_the_title($prevpost->ID);
}else{
$prevpost_id = "";
$prevpost_title = "";
}
}else{
$nextpost_id = "";
$nextpost_title = "";
$prevpost_id = "";
$prevpost_title = "";
}
$post_tags_array = get_the_tags($postid);
if($post_tags_array){
foreach($post_tags_array as $post_tags){
$tagumei[] = $post_tags->name;
$taguid[] = $post_tags->term_id;
}
$tagumei2 = implode("','",$tagumei);
$tagumei4 = implode(",",$tagumei);
$tagumei3 = "array('".$tagumei2."')";
$taguid2 = implode("','",$taguid);
$taguid3 = "array('".$taguid2."')";
$tagusuu = count($tagumei);
}else{
$tagumei3 = 0;
$taguid3 = 0;
$tagumei4 = "";
$tagusuu = 0;
}
unset($tagumei);
unset($taguid);
unset($post_tags_array);
////////////////////
$postid_all[] = $postid;
$maincache = $dirpath."/kijikyashu/".$postid.".php";
$maincache2 = $dirpath."/kijikyashu/".$postid."b.php";
$maincache_allid = $dirpath."/kijikyashu/postid_all.php";
//メイン記事表示用
$postdata = <<<EOM2
<?php
\$postid = '{$postid}';
\$title = '{$title}';
\$permalink = '{$permalink}';
\$text = '{$text}';
\$eyecatch_medium_large = '{$eyecatch_medium_large[0]}';
\$eyecatch_medium_largew = '{$eyecatch_medium_large[1]}';
\$eyecatch_medium_largeh = '{$eyecatch_medium_large[2]}';
\$eyecatch_full = '{$eyecatch_full[0]}';
\$cat_id = '{$cat_id}';
\$cat_name = '{$cat_name}';
\$cat_slug = '{$cat_slug}';
\$posted_date = '{$posted_date}';
\$the_modified_date1 = '{$the_modified_date1}';
\$the_modified_date2 = '{$the_modified_date2}';
\$nextpost_id = '{$nextpost_id}';
\$nextpost_title = '{$nextpost_title}';
\$prevpost_id = '{$prevpost_id}';
\$prevpost_title = '{$prevpost_title}';
\$tagumei = {$tagumei3};
\$tagumei2 = '{$tagumei4}';
\$taguid = {$taguid3};
\$datePublished = '{$datePublished}';
\$tagusuu = '{$tagusuu}';
?>
EOM2;
//記事一覧表示用(必要なデータだけのファイルにする)
$postdata2 = <<<EOM2
<?php
\$postid2 = '{$postid}';
\$title2 = '{$title}';
\$permalink2 = '{$permalink}';
\$eyecatch_medium_large2 = '{$eyecatch_medium_large[0]}';
\$eyecatch_full2 = '{$eyecatch_full[0]}';
\$cat_id2 = '{$cat_id}';
\$cat_name2 = '{$cat_name}';
\$cat_slug2 = '{$cat_slug}';
\$posted_date2 = '{$posted_date}';
?>
EOM2;
file_put_contents($maincache, $postdata);
file_put_contents($maincache2, $postdata2);
endwhile;
endif;
wp_reset_postdata();
$postid_all2 = "'".implode("','",$postid_all)."'";
$postid_all2 = "<?php \$postid_all = array(".$postid_all2.") ?>";
file_put_contents($maincache_allid, $postid_all2);
unset($postid_all);
////////////////ここからカテゴリごと記事ID取得
$categories = get_categories();
foreach($categories as $category) :
$catidall[] = $category->term_id;
endforeach;
$katesuu = count($catidall);
for($i=0;$i<$katesuu;$i++){
$catkyashu = $dirpath."/kijikyashu/cat".$catidall[$i].".php";
$args = array(
'posts_per_page' => -1,
'cat' => $catidall[$i],
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$postid_all[] = get_the_ID();
endwhile;
endif;
wp_reset_postdata();
$postid_all2 = "'".implode("','",$postid_all)."'";
$postid_all2 = "<?php \$catpostid_all = array(".$postid_all2.") ?>";
file_put_contents($catkyashu, $postid_all2);
unset($postid_all);
}
////////////////ここからタグごと記事ID取得
$tagushutoku = get_tags();
foreach($tagushutoku as $tagushutoku2) :
$tagidall[] = $tagushutoku2->term_id;
endforeach;
$tagsuu = count($tagidall);
for($i=0;$i<$tagsuu;$i++){
$tagkyashu = $dirpath."/kijikyashu/tag".$tagidall[$i].".php";
$args = array(
'posts_per_page' => -1,
'tag_id' => $tagidall[$i],
);
$the_query = new WP_Query($args);
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
$postid_all[] = get_the_ID();
endwhile;
endif;
wp_reset_postdata();
$postid_all2 = "'".implode("','",$postid_all)."'";
$postid_all2 = "<?php \$tagpostid_all = array(".$postid_all2.") ?>";
file_put_contents($tagkyashu, $postid_all2);
unset($postid_all);
}
?>
全記事取得して、データを抜き取って保存しているだけ。
要はこのようなデータを作るだけです。
<1375.php>
<?php
$postid = '1375';
$title = 'ワードプレスは記事データのキャッシュが必須!という話';
$permalink = 'https://doudonn.com/wa-dopuresu/1375/';
$text = 'ワードプレスはとにかく軽くするベテランほど軽さを重視するだろう。良いサーバーも大事ですが、軽くすることの方が大事です。このあたり…';
$eyecatch_medium_large = 'https://doudonn.com/tenpu/2022/12/ai1375-768x403.jpg';
$eyecatch_medium_largew = '768';
$eyecatch_medium_largeh = '403';
$eyecatch_full = 'https://doudonn.com/tenpu/2022/12/ai1375.jpg';
$cat_id = '17';
$cat_name = 'ワードプレス';
$cat_slug = 'wa-dopuresu';
$posted_date = '2022/12/25';
$the_modified_date1 = '2022-12-28T18:48:13+09:00';
$the_modified_date2 = '2022/12/28';
$nextpost_id = 'https://doudonn.com/wa-dopuresu/1398/';
$nextpost_title = 'ワードプレスで絶対やる初期設定5選(あまり書かれていないやつ)';
$prevpost_id = '';
$prevpost_title = '';
$tagumei = array('キャッシュ');
$tagumei2 = 'キャッシュ';
$taguid = array('20');
$datePublished = '2022-12-25T17:20:22+09:00';
$tagusuu = '1';
?>
<postid_all.php>
<?php $postid_all = array('1638','1619','1598','1588','1578','1563','1555','1533','1501','1495','1467','1321','1435','1373','1398','1375','1340','1336','1325') ?>
<cat17.php>
<?php $catpostid_all = array('1619','1598','1563','1501','1373','1398','1375') ?>
<tag20.php>
<?php $tagpostid_all = array('1501','1375') ?>
簡単なコードなので見ればやっていることはわかると思います。
「記事ID.php」で保存し、表示する時にそれを読み込むだけ。
あと、ランダム表示用に全記事IDも保存しています。
自分は記事作成ごとに手動で更新しています。
固定ページのphpに書いてる。
5、どのくらい軽くなるのか?
WP_Query | キャッシュ | 改善率 | |
処理時間 | 0.005108 | 0.000583 | 876% |
0.004908 | 0.000566 | 867% | |
0.005058 | 0.000580 | 872% | |
メモリ使用量 | 253400 | 1184 | 21402% |
242552 | 992 | 24451% | |
250248 | 1088 | 23001% |
キャッシュしたファイルを読み込めばメモリ使用量を大きく削減できます。
アクセス集中にかなり強くなる。
静的キャッシュではできない動的処理(ランダム表示等)もできる。
良いことしかないので、これは絶対にやっておきたい。
まとめ
いつ来るかわからないアクセス集中に備えよう。
誰もがいつTwitterで拡散されてバズるかわからない。
そんな時、初期設定なワードプレスなら確実に鯖落ちします。
面倒でもキャッシュ処理はいろいろとやっておこう。
これさえ気を付けていれば、エックスサーバーでもほぼ大丈夫です。
--
ちなみに、URL名は英語にするとスパムとかハッキングとかが物凄いので、
自分はローマ字にしています。
かっこつけてセキュリティリスクを高めてはいけない。