为 PIX 主题添加 Redis 缓存支持
前言
前面的文章【WP提升页面切换速度(bfcache) 】讲了如何将admin-ajax.php的请求缓存到用户本地,并且通过链接预取Instant.page实现无缝切换页面,但是无法对首次加载进行提速,这篇文章以PIX主题为例,将请求通过Redis缓存,真正的提升访问速度。
像文章列表和片刻列表这些不需要频繁刷新的内容,缓存当然没有任何影响。本文仅展示缓存这两个,其他请求可以让AI改。
步骤
前提条件
- PHP必须安装Redis扩展
- wp必须安装并启用Redis Object Cache插件
修改前先备份主题代码,修改后有什么bug可以评论区交流,可以只学习思路自己动手。
通用缓存函数
将以下代码添加到主题根目录下的function.php中
function wp_ajax_redis_cache($callback, $ttl = 600){
if (is_user_logged_in()) {
$result = $callback();
wp_send_json($result);
}
$version = wp_cache_get('ajax_cache_version', 'ajax');
if(!$version){
$version = 1;
wp_cache_set('ajax_cache_version', $version, 'ajax');
}
$key_data = [
'v' => $version,
'action' => $_REQUEST['action'] ?? '',
'cat' => $_REQUEST['cat'] ?? '',
'paged' => $_REQUEST['paged'] ?? ''
];
$cache_key = 'ajax_cache_' . md5(json_encode($key_data));
$cached = wp_cache_get($cache_key, 'ajax');
if($cached !== false){
wp_send_json($cached);
}
$result = $callback();
if(!empty($result['content'])){
wp_cache_set($cache_key, $result, 'ajax', $ttl);
}
wp_send_json($result);
}
增加了用户登录校验,不会对登录用户进行缓存或读取缓存。
修改文章列表加载函数
代码位置:pix/inc/pix-post.php : 查找到blog_mod_loop()函数,替换为以下代码。
function blog_mod_loop(){
wp_ajax_redis_cache(function(){
global $wp_query;
$sticky_html = '';
$cat = !empty($_REQUEST['cat']) ? intval($_REQUEST['cat']) : '';
$sticky = get_option('sticky_posts');
$args = array(
'post_type' => 'post',
'cat' => $cat,
'post_status' => 'publish',
);
if(empty($cat)){
$args['post__not_in'] = $sticky;
$sticky_html = posts_sticky_loop();
}
query_posts($args);
if(have_posts()):
ob_start();
while(have_posts()): the_post();
post_show_type();
endwhile;
$posts_html = ob_get_clean();
else:
$posts_html = '<p class="no_posts"><img class="s_nodata" src="'.THEME_URL.'/img/nodata.png"></p>';
endif;
if(get_op('qiniu_cdn')) {
$posts_html = ajax_qiniu_cdn_replace($posts_html);
}
return [
'posts' => json_encode($wp_query->query_vars),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $sticky_html.$posts_html
];
}, 600);
}
代码里的600指的是缓存600秒,可以自己调整,像文章列表,每天刷新一次缓存都没问题,毕竟如果只有你一个人发布文章,可以手动通过Redis插件刷新缓存。我建议设置为21600(6小时)。
修改片刻列表加载函数
代码位置: pix/inc/pix-moment.php : 查找函数moment_cat_filter(),替换。
function moment_cat_filter(){
wp_ajax_redis_cache(function(){
if (session_id()) {
session_write_close();
}
global $wp_query;
$sticky_html = '';
$cat = !empty($_REQUEST['cat']) ? intval($_REQUEST['cat']) : get_all_topics_id();
$sticky = get_option('sticky_posts');
$args = array(
'post_type' => 'moment',
'tax_query' => array(
array(
'taxonomy' => 'moments',
'field' => 'term_id',
'terms' => $cat,
),
),
'post_status' => 'publish',
);
// 只在全部分类显示置顶
if(empty($_REQUEST['cat'])){
$args['post__not_in'] = $sticky;
$sticky_html = moment_sticky_loop();
}
query_posts($args);
if(have_posts()):
ob_start();
while(have_posts()): the_post();
get_template_part('tpl/content', 'moment');
endwhile;
$posts_html = ob_get_clean();
else:
$posts_html = '<p class="no_posts"><img class="s_nodata" src="'.THEME_URL.'/img/nodata.png"></p>';
endif;
$output = array();
$post_list = $wp_query->posts;
foreach($post_list as $list){
$pid = $list->ID;
$data = array(
'content' => $list->post_content,
'pid' => $pid
);
$output[] = $data;
}
if(get_op('qiniu_cdn')){
$posts_html = ajax_qiniu_cdn_replace($posts_html);
$sticky_html = ajax_qiniu_cdn_replace($sticky_html);
}
return array(
'posts' => json_encode($wp_query->query_vars),
'max_page' => $wp_query->max_num_pages,
'found_posts' => $wp_query->found_posts,
'content' => $sticky_html.$posts_html,
'post_data' => $output,
);
}, 600);
}
修改后,文章和片刻列表的请求都会被缓存到Redis,用户端可以直接获取结果,不需要经过复杂处理。
自动刷新缓存
以下代码同样添加到function.php
function bump_ajax_cache_version($post_id){
if (wp_is_post_revision($post_id)) {
return;
}
$version = wp_cache_get('ajax_cache_version', 'ajax');
if(!$version){
$version = 1;
}
wp_cache_set('ajax_cache_version', $version + 1, 'ajax');
}
add_action('save_post', 'bump_ajax_cache_version');
add_action('deleted_post', 'bump_ajax_cache_version');
add_action('trash_post', 'bump_ajax_cache_version');
发布/更新/删除文章时自动刷新Redis缓存。
总结
如果你追求极致速度,可以了解Nginx microcache,毕竟Redis缓存仍然通过WP实现。
有bug麻烦在评论反馈一下,谢谢[偷笑]。
「摸鱼小屋」 (atmoyu.com)版权所有,引用、转载时必须标明原文出处!







空空如也!