为什么admin-ajax加载速度会变慢?有什么方法可以加快它的速度?

时间:2019-04-04 作者:Javi Torre Sustaeta

我正在为WoodPress开发一个使用woocommerce的主题。目前,我开发了一个新页面,展示产品。最初,我没有使用ajax就完成了页面和类别过滤器,一切都很好。然而,设计师不喜欢在应用过滤器时重新加载页面,然后我使用wordpress的ajax再次开发了所有内容,因为纯ajax不起作用。现在页面运行正常,第一次加载和过滤器使用ajax。但问题如下:当页面调用admin ajax时,会延迟3-5秒。然而,当我在localhost中测试时,持续时间是瞬时的。

这是函数中的函数。php:

add_action(\'wp_ajax_nopriv_filter_category_action\',\'educaforma_filter_ajax\');
add_action(\'wp_ajax_filter_category_action\',\'educaforma_filter_ajax\');

function educaforma_filter_ajax(){
$category_filter = "";
if(isset($_POST[\'category\'])){
    if($_POST[\'category\'] == "todos"){
        $category_filter = "";
    }
    else{
        $category_filter = $_POST[\'category\'];
    }
}
$output = "";
$params = array(
    \'product_cat\' => $category_filter,
    \'posts_per_page\' => 15,
    \'post_type\' => \'product\',
);
$wc_query = new WP_Query($params);
$count = $wc_query->post_count;
$cont_post = 0; 
    if ($wc_query->have_posts()) : 
    while ($wc_query->have_posts()) :
            $wc_query->the_post(); 
            global $product;
            if($cont_post == 0): 

                $output .= "<div class = \'row\'>"; 

            elseif($cont_post%3 == 0):

                $output .= "</div>"; 
                $output .= "<div class = \'row\'>"; 

            endif;

    $output .= "<div class =\'col-md-4 col-sm-4\'>";
        // <!-- <div class="container-course"> -->
        $output .= "<a class=\'list-course\' href=\'".$product->get_permalink()."\'>";

            // $output .= the_post_thumbnail();
            // $output .= $product->get_image(artiest,1,1); 
            $attachment_id = get_post_thumbnail_id( $product->id );
            $attachment = wp_get_attachment_image_src($attachment_id, \'full\' );
            $output .= "<div class=\'image-product\' style=\'position: relative;
                                    background-repeat: no-repeat;
                                    background-position: 50% 50%;
                                    background-size: cover;
                                    background-clip: border-box;
                                    box-sizing: border-box;
                                    overflow: hidden;
                                    height: 180px;
                                    width: 100%;
                                    background-image: url(".$attachment[0].") !important;
                                    \'>
                                    <div class=\'darken-image\'></div>
                        </div>";
            $output .= "<div class=\'separator\'></div>";
            $output .= "<div class=\'container-course\'>";
                $output .= "<h3 class=\'title-course\'>";
                // $output .= the_title(); 
                $output .= $product->get_title();

                $output .= "</h3>";
             //the_excerpt(); 
             $output .= "<p class=\'title-attribute\'>Curso:  <span class=\'value-attribute\'>".$product->get_attribute(\'Curso\')." </span></p>";
             $output .= "<p class=\'title-attribute\'>Inicio:  <span class=\'value-attribute\'>". $product->get_attribute(\'Inicio\')." </span></p>";
             $output .= "<p class=\'title-attribute\'>Finalización:  <span class=\'value-attribute\'>". $product->get_attribute(\'Finalizacion\')." </span></p>";
             $output .= "<p class=\'title-attribute\'>Precio:  <span class=\'value-attribute\'>".$product->get_attribute(\'Precio\')." </span></p>";
             $output .= "<p class=\'title-attribute\'>Avalado por: <span class=\'value-attribute\'> ".$product->get_attribute(\'Avalado\')." </span></p>";
            $output .= "</div>";
        $output .= "</a>";
    $output .= "</div>";

     $cont_post++; 
  endwhile; 
  wp_reset_postdata(); 
  else:  
    $ouput.= "<li>";
    $ouput .= "No hay cursos";
    $output.="</li>";
  endif; 
echo $output;
}
这是javascript ajax的一部分:

function($){
$(document).on(\'click\',\'#negocios\',function(e){
    e.preventDefault();

    $.ajax({
        url: filter_categories_vars.ajaxurl,
        type: \'POST\',
        data: { 
            action: \'filter_category_action\', // The name of the WP action
            category: \'negocios-internacionales\',
        },
        // dataType: \'json\',
        complete : function ( ) {   // optionally to develop in any case: success or error
                }, 
        success: function ( response ) {     // to develop in case of success
                $(\'#cursos_catalogo\').fadeOut(600)
                setTimeout(() => {

                    $(\'#cursos_catalogo\').html(response.substring(0,(response.length - 1)));  
                    $(\'#cursos_catalogo\').fadeIn(600)
                }, 600);
                document.getElementById("negocios").classList.add("filtered");
                document.getElementById("todos").classList.remove("filtered");
                document.getElementById("turismo").classList.remove("filtered");
                document.getElementById("habilidades").classList.remove("filtered");

        },
        error: function ( errorThrown ) {   // to develop in case of error
                    console.log("ERROR")
                    console.log( errorThrown ); 
                }, 
    });

});

duration loading

我想知道两件事:

为什么我不能使用普通的ajax?

为什么管理ajax如此之慢,我能做些什么来减少这种延迟?

谢谢

1 个回复
SO网友:phatskat

可能的解决方案我认为您的问题的一部分是\\WP_Query 调用——查询数据库对于进行快速、高效的AJAX调用来说并不“便宜”,但在您的情况下也无法真正避免。

您可以采取的一种方法是将查询结果缓存一段时间,至少在这种情况下,您会对一个类别有一个最初的缓慢响应,然后对后续查询有一个快速响应。

function educaforma_filter_ajax(){
    $category_filter = "";

    if(isset($_POST[\'category\'])){
        if($_POST[\'category\'] == "todos"){
            $category_filter = "";
        }
        else{
            $category_filter = $_POST[\'category\'];
        }
    }

    $output = "";
    $params = array(
        \'product_cat\'    => $category_filter,
        \'posts_per_page\' => 15,
        \'post_type\'      => \'product\',
    );

    // Create a cache key based on the parameters and try to get a transient.
    $cache_key      = "educaforma_filter_results_" . implode( \'_\', $params );
    $cached_results = get_transient( $cache_key);

    if ( ! empty( $cached_results ) ) {
        echo $cached_results;
        exit;
    }

    $wc_query = new WP_Query($params);
    $count = $wc_query->post_count;
    $cont_post = 0; 
    if ($wc_query->have_posts()) : 
        while ($wc_query->have_posts()) :
            $wc_query->the_post(); 
    global $product;
    if($cont_post == 0): 

        $output .= "<div class = \'row\'>"; 

    elseif($cont_post%3 == 0):

        $output .= "</div>"; 
    $output .= "<div class = \'row\'>"; 

    endif;

    $output .= "<div class =\'col-md-4 col-sm-4\'>";
    // <!-- <div class="container-course"> -->
    $output .= "<a class=\'list-course\' href=\'".$product->get_permalink()."\'>";

    // $output .= the_post_thumbnail();
    // $output .= $product->get_image(artiest,1,1); 
    $attachment_id = get_post_thumbnail_id( $product->id );
    $attachment = wp_get_attachment_image_src($attachment_id, \'full\' );
    $output .= "<div class=\'image-product\' style=\'position: relative;
    background-repeat: no-repeat;
    background-position: 50% 50%;
    background-size: cover;
    background-clip: border-box;
    box-sizing: border-box;
overflow: hidden;
height: 180px;
width: 100%;
       background-image: url(".$attachment[0].") !important;
       \'>
           <div class=\'darken-image\'></div>
           </div>";
       $output .= "<div class=\'separator\'></div>";
       $output .= "<div class=\'container-course\'>";
       $output .= "<h3 class=\'title-course\'>";
       // $output .= the_title(); 
       $output .= $product->get_title();

       $output .= "</h3>";
       //the_excerpt(); 
       $output .= "<p class=\'title-attribute\'>Curso:  <span class=\'value-attribute\'>".$product->get_attribute(\'Curso\')." </span></p>";
       $output .= "<p class=\'title-attribute\'>Inicio:  <span class=\'value-attribute\'>". $product->get_attribute(\'Inicio\')." </span></p>";
       $output .= "<p class=\'title-attribute\'>Finalización:  <span class=\'value-attribute\'>". $product->get_attribute(\'Finalizacion\')." </span></p>";
       $output .= "<p class=\'title-attribute\'>Precio:  <span class=\'value-attribute\'>".$product->get_attribute(\'Precio\')." </span></p>";
       $output .= "<p class=\'title-attribute\'>Avalado por: <span class=\'value-attribute\'> ".$product->get_attribute(\'Avalado\')." </span></p>";
       $output .= "</div>";
       $output .= "</a>";
       $output .= "</div>";

       $cont_post++; 
       endwhile; 
       wp_reset_postdata(); 
else:  
       $ouput.= "<li>";
       $ouput .= "No hay cursos";
       $output.="</li>";
       endif; 

    // Set the transient here!
    set_transient( $cache_key, $output, DAY_IN_SECONDS );
    echo $output;

}
在上面的代码片段中,我添加了以下几行:

    // Create a cache key based on the parameters and try to get a transient.
    $cache_key      = "educaforma_filter_results_" . implode( \'_\', $params );
    $cached_results = get_transient( $cache_key);

    if ( ! empty( $cached_results ) ) {
        echo $cached_results;
        exit;
    }
这将基于参数创建一个“密钥”,并尝试找到与该名称匹配的瞬态。进一步如下:

    // Set the transient here!
    set_transient( $cache_key, $output, DAY_IN_SECONDS );
    echo $output;
如果我们发现瞬态时没有提前停止,则会设置瞬态。现在,下次有人查询同一类别时,将设置瞬态,并应快速返回结果。

请注意,过期时间设置为24小时(DAY_IN_SECONDS). 您可能希望它变短或变长,并且根据您更新内容的频率,您可能需要一些其他方法来使瞬态无效。

关于查询速度慢,查询速度慢的一个原因是它使用了自定义参数,product_cat, 我假设您正在某个地方对查询的某个过滤器进行解析,这可能与术语关系有关。这意味着WordPress正在连接多个表,根据您的数据库,这可能会有点慢。

此外,您的响应延迟了600毫秒setTimeout - 我知道这并不算大,但请考虑一下,您在已经很慢的响应上添加了超过半秒钟的时间。

我不知道除了缓存之外,你还能做些什么来更快地提供内容,至少在不深入了解网站内部的情况下。添加某种形式的视觉反馈(如加载微调器)至少可以让用户知道发生了什么事情,至少可以帮助用户感知站点的加载时间(即使实际上没有更快)。

相关推荐

注册表AJAX检查现有用户名(简单版本)

我知道与这个主题相关的问题已经很多了,但我正在寻找一种简单的方法来对现有用户名进行ajax检查。因此,基本上我有HTML表单和两个函数(在function.php中)——一个用于发出ajax请求,另一个用于进行DB查找。注意:我使用的是WP Multisite。The HTML Form:<form method=\"post\" name=\"register_user\"> <p> <label for=\"register_name\"&g