优化自定义文章类型筛选中admin-ajax.php请求速度
WordPress自定义文章类型分类筛选加载慢的优化方案
我在WordPress中实现了基于分类的自定义文章类型(CPT)JS筛选功能,选择分类后会加载包含ACF字段的HTML盒子,但加载过程耗时1秒以上,交互体验不够流畅。以下是现有代码及优化方案:
现有代码
1. JS文件(filters.js)
(function($){ $(document).ready(function(){ $(document).on('click', '.js-filter-item > a', function(e){ e.preventDefault(); var category = $(this).data('category'); $.ajax({ url:wp_ajax.ajax_url, data: { action: 'filter', category: category }, type: 'post', success: function(result) { $('.js-filter').html(result); }, error: function(result) { console.warn(result); } }); }); }); })(jQuery);
2. HTML模板文件(content_pozice_box.php)
<a href="<?php echo get_permalink();?>"><div class="vypis_pozice"> <div class="projekt-wrapper"> <?php $projekt = get_field('projekt'); if( get_field('projekt') == 'XXX' ) { ?> <div class="logo-wrapper"> <img src="https://YYY.png" class="logo-wrapper-img"> </div><?php } if( get_field('projekt') == 'YYY' ) { ?> <div class="logo-wrapper"> <img src="https://XXX.png" class="logo-wrapper-img"> </div> <?php } ?> <div class="field_projekt"><h3><?php the_field('projekt');?></h3><div class="field_AAA">AAA: <?php if ( get_field( 'AAA' ) ): ?> <?php the_field('AAA');?> <?php else: // field_name returned false ?> dohodou <?php endif; // end of if field_name logic ?> </div></div> </div> <?php the_title('<h3>', '</h3>'); ?> <div class="location-wrapper"> <div class="BBB"><img src="https://BBB.png"><?php the_field('BBB');?></div> <div class="CCC"><img src="https://CCC.png"><?php the_field('CCC');?></div> </div> <div class="DDD"><?php $cat = get_the_category(); echo $cat[0]->cat_name; ?></div><div class="job-button">Otevřít</div> </div></a>
3. PHP脚本(加载、Ajax处理)
function load_scripts() { wp_enqueue_script('ajax', get_stylesheet_directory_uri() . '/' . 'template-parts/' .'filters.js', array('jquery'), NULL, true); wp_localize_script('ajax' , 'wp_ajax', array('ajax_url' => admin_url('admin-ajax.php')) ); } add_action( 'wp_enqueue_scripts', 'load_scripts'); add_action( 'wp_ajax_nopriv_filter', 'filter_ajax' ); add_action( 'wp_ajax_filter', 'filter_ajax' ); function filter_ajax() { $category = $_POST['category']; $args = array( 'post_type' => 'pozice', 'posts_per_page' => -1 ); if(isset($category)) { $args['category__in'] = array($category); } $query = new WP_Query($args); if($query->have_posts()) : while($query->have_posts()) : $query->the_post(); include("content_pozice_box.php"); endwhile; endif; wp_reset_postdata(); die(); }
优化方案
1. 数据库查询优化
- 减少字段查询:在WP_Query中添加
'fields' => 'ids',只获取文章ID,避免查询不必要的数据库字段:$args = array( 'post_type' => 'pozice', 'posts_per_page' => -1, 'fields' => 'ids' // 只返回文章ID ); - 缓存查询结果:用WordPress内置缓存函数缓存查询结果,避免重复请求数据库:
$cache_key = 'filter_pozice_' . $category; $posts_ids = wp_cache_get($cache_key); if (!$posts_ids) { $query = new WP_Query($args); $posts_ids = $query->posts; wp_cache_set($cache_key, $posts_ids, '', 3600); // 缓存1小时 } - 修正分类参数:如果自定义文章类型使用的是自定义分类法,
category__in不适配,改用tax_query:if(isset($category)) { $args['tax_query'] = array( array( 'taxonomy' => '你的自定义分类法slug', // 替换成实际的分类法slug 'field' => 'term_id', 'terms' => $category, ), ); }
2. ACF字段加载优化
- 批量获取字段:用
get_fields($post_id)一次性获取所有ACF字段,减少多次get_field调用的开销:$fields = get_fields(get_the_ID()); $projekt = $fields['projekt'] ?? ''; $aaa = $fields['AAA'] ?? 'dohodou'; - 避免重复调用:模板中重复使用的字段先赋值给变量,比如
$projekt = get_field('projekt');,后续判断和输出都用这个变量,不要重复调用get_field。
3. 前端交互优化
- 添加加载状态:点击筛选后立即显示加载提示,让用户感知到正在处理:
$(document).on('click', '.js-filter-item > a', function(e){ e.preventDefault(); var category = $(this).data('category'); // 显示加载动画 $('.js-filter').html('<div class="loading-state">正在加载...</div>'); $.ajax({ url: wp_ajax.ajax_url, data: { action: 'filter', category: category }, type: 'post', success: function(result) { $('.js-filter').html(result); }, error: function(result) { console.warn(result); $('.js-filter').html('<div class="error-state">加载失败,请重试</div>'); } }); }); - 防抖处理:防止用户快速点击多个分类触发重复请求:
let debounceTimer; $(document).on('click', '.js-filter-item > a', function(e){ e.preventDefault(); clearTimeout(debounceTimer); var category = $(this).data('category'); $('.js-filter').html('<div class="loading-state">正在加载...</div>'); debounceTimer = setTimeout(() => { $.ajax({ url: wp_ajax.ajax_url, data: { action: 'filter', category: category }, type: 'post', success: function(result) { $('.js-filter').html(result); }, error: function(result) { console.warn(result); $('.js-filter').html('<div class="error-state">加载失败,请重试</div>'); } }); }, 300); // 300毫秒内重复点击只执行最后一次 });
4. 服务器端优化
- 启用PHP的OPcache扩展,加速脚本执行;
- 在ACF设置中开启字段缓存,减少ACF的数据库查询;
- 使用页面缓存插件缓存Ajax请求结果或页面片段。
内容的提问来源于stack exchange,提问作者JohnK
相关产品推荐
相关产品推荐

