【问题标题】:Improving the speed of a custom infinite scroll提高自定义无限滚动的速度
【发布时间】:2019-07-02 03:50:57
【问题描述】:

我有一个自定义的无限滚动,它工作得很好,但它真的很慢。这是处理 ajax 请求的脚本:-

function ga_infinite_scroll() {//trigger this on infinite scroll
  add_filter( 'woocommerce_get_price_html', 'ga_show_price' );//filter to fix price range
  if(empty($_POST['search_term'] )){
    $params = json_decode( stripslashes( $_POST['query'] ), true );
    $params['post_status'] = 'publish';
    $params['posts_per_page'] = get_option('posts_per_page');
    $params['post_type'] = 'product';
    $params['paged'] = $_POST['page'] + 1; // we need next page to be loaded

  }
  else{//search  logic here
      $search_query = json_decode( stripslashes( $_POST['search_posts'] ), true );
      $search_query['post_status'] = 'publish';
      $search_query['posts_per_page'] = get_option('posts_per_page');
      $search_query['paged'] = $_POST['page'] + 1;
      wc_set_loop_prop( 'total', $_POST['search_count'] );
      $params = $search_query;

  }

  ob_start();           
  query_posts( $params);

  if ( have_posts() ) {//product loop
        if ( wc_get_loop_prop( 'total' ) ) {
              while ( have_posts() ) {
                the_post();
                wc_get_template_part( 'content', 'product' );
              }
            }
    } 

    $data = ob_get_clean();
    die($data); 
    exit;
}
add_action( 'wp_ajax_ga_infinite_scroll', 'ga_infinite_scroll' );
add_action( 'wp_ajax_nopriv_ga_infinite_scroll', 'ga_infinite_scroll' );

这是我对问题的简要描述Improving the performance of a custom developed scroll 的另一篇文章。这是 ga_show_price 的代码。

    function ga_show_price( $price ) {


   global $post, $product, $reg_price_field_slug, $sale_price_field_slug, $user_currency, $wp_query,$wp_object_cache;


   if( count($product->get_children()) !== 0 ) {

       $variations = $product->get_children();
       $regularPriceList = [];
       $salePriceList = [];
       $lowestPrice;
       $salePrice;

     // die("here");
       if( $product->is_on_sale() ) {
           // NOTE: ADD caching HERE!!
           if( false === get_transient( 'sales_price' ) ) {
           foreach( $variations as $variation ) {
               array_push($salePriceList, get_post_meta( $variation, $reg_price_field_slug, true ) );
           }


           set_transient( 'sales_price', $salePriceList, 12 * HOUR_IN_SECONDS );
          }
          else{
            $salePriceList =  get_transient( 'sales_price');
          }
          $salePrice = min($salePriceList);
          $price = add_proper_decimal($salePrice);
           return get_woocommerce_currency_symbol() . $price . ' ' . $user_currency;

       } else {
           // NOTE: ADD caching HERE!!
           if( false === get_transient( 'reg_price' ) ) {
           foreach( $variations as $variation ) {
               array_push($regularPriceList, get_post_meta( $variation, $reg_price_field_slug, true ) );
           }

           set_transient( 'reg_price', $regularPriceList, 12 * HOUR_IN_SECONDS );
          }
          else{
            $regularPriceList =  get_transient( 'reg_price');
          }

           $lowestPrice = min($regularPriceList);
           $price = add_proper_decimal($lowestPrice);



           return get_woocommerce_currency_symbol() . $price . ' ' . $user_currency;
       }
   } else {
       $price = get_post_meta( $post->ID, $reg_price_field_slug, true );
       $price = add_proper_decimal($price); // pr( $price );

       if ( $price == '0.00' ) {
           return 'Call for Price';
       }

       return get_woocommerce_currency_symbol() . $price . ' ' . $user_currency;
   }

}

我的 javascript 在这里:-

jQuery(document).ready( function($) {
   var  url = window.location.origin + '/wp-admin/admin-ajax.php',
    canBeLoaded=true,
     bottomOffset = 2000; // the distance (in px) from the page bottom when you want to load more posts

    $(window).scroll(function(){
        var data = {
            'action': 'ga_infinite_scroll',
            'query': my_ajax_object.posts,
            'page' : my_ajax_object.current_page,
            //'search_results' : my_ajax_object.ga_search_results,
            'search_count' : my_ajax_object.ga_search_count,
            'search_posts': my_ajax_object.ga_search_posts,
            'search_term' : my_ajax_object.ga_search_term,
            'user_currency': my_ajax_object.user_currency,
            'reg_price_slug': my_ajax_object.reg_price_field_slug
        };


        if( $(document).scrollTop() > ( $(document).height() - bottomOffset ) && canBeLoaded == true ){

                $.ajax({//limit the ajax calls
                    url : url,
                    data:data,
                    type:'POST',                    
                    beforeSend: function( xhr ){
                        // you can also add your own preloader here
                        // you see, the AJAX call is in process, we shouldn't run it again until complete
                        //console.log(data.search_term);
                        $('#ajax-loader').show();  
                        canBeLoaded = false; 
                    },
                    success:function(data){
                        if( data ) {
                            $('#multiple-products .columns-3 .products ').find('li:last-of-type').after( data ); // where to insert posts

                            //console.log(url);
                            canBeLoaded = true; // the ajax is completed, now we can run it again
                            my_ajax_object.current_page++;
                            $('#ajax-loader').hide();
                        }
                        else{
                            $('#ajax-loader').html('End of products...').delay(1000).fadeOut(); 
                            return;
                        }

                    }
                });

        }
    });


    //setting if it's a search

});

有没有一种方法可以在 ajax 请求处理脚本(ga_infinite_scroll)之外使用这个 woocommerce_get_price_html 过滤器,因为在 ajax 处理脚本中使用它的速度真的很昂贵?我尝试在 ga_show_price() 中使用瞬变。这里如何实现其他类型的缓存来提高无限滚动的速度?

【问题讨论】:

  • 在 ga_show_price 函数中添加了变化产品价格的瞬态并更新了上面的代码

标签: php wordpress optimization woocommerce


【解决方案1】:

@Mikepote 对 ga_price 的建议提高了速度,但基于独特的瞬态提高了速度编辑主产品循环。我特此附上我的代码:-

  if( empty(get_transient('ga_loop_products_'.md5(serialize($params))))){ //using md5 and serialize(for 32digit) to assign a unique name to the given set of params



     query_posts( $params);

     ob_start(); 

     add_filter( 'woocommerce_get_price_html', 'ga_show_price' );//filter to fix price range

      if ( have_posts() ) {//product loop
            if ( wc_get_loop_prop( 'total' ) ) {
                  while ( have_posts() ) {

                    the_post();

                    wc_get_template_part( 'content', 'product' );
                  }
                }
        } 
        $data = ob_get_clean();
          // $ga_loop = get_transient('ga_loop_products_'.md5(serialize($params)));
          set_transient( 'ga_loop_products_'.md5(serialize($params)), $data, 24 * 60 ); // 1 day cache
      }
      else{


         $data=  get_transient('ga_loop_products_'.md5(serialize($params)));


      }

       wp_reset_query();

【讨论】:

    【解决方案2】:

    因此,使用瞬变可能是这里最好的“简单”答案,而无需进行一些重大的返工。但是,您的 ga_show_price() 函数存在一些问题。

    因此,您希望始终尽量减少从代码中调用的数据库调用量或冗长的函数,以加快处理速度。

    1. 瞬态具有全局名称。因此,如果您对一种产品使用名为 sales_price 的东西,那么一旦您将它用于另一种产品,它仍将保持先前产品的价值。您可能需要做的是为所有瞬态生成一个唯一的名称。比如:set_transient('price_'.$product->getSKU(), ...)

    2. $variations = $product->get_children(); - 您正在使用产品的所有子项加载 $variations 变量,这可能需要相当长的时间并且涉及相当多的 db 调用,那么如果您已经对此有一个瞬态产品,从未使用过变体!仅当您还没有产品的缓存值时才运行此行。

    3. 一个较小的问题,但每次有缓存值时,您都会调用 get_transient 两次。一次检查它是否为假,然后再次实际检索该值。可能看起来是一件小事,但如果你有 100 多个产品加载,它就会加起来。

    我喜欢用我的瞬态来做这个:

     $value = get_transient('something');
     if ($value === false)
     {
        $value = some_long_calculation();
        set_transient('something', $value, ...);
     }
    
     //Now use $value here.
    
    1. 更积极地使用缓存。商品多久从打折变为不打折?一天不超过一次?然后只缓存整个函数的计算,而不是先检查它是否有销售价格或正常价格。

    警告:瞬态的名称和值有一个最大长度,因此您不能在其中存储太多。此外,它们被设计为仅存储几个值,而不是系统中每个产品的价格。

    如果是这种情况,您最好考虑将值缓存在每个产品的自定义字段中?您可以附加挂钩,以便每次更新产品时,它都会自动更新计算的价格自定义字段。

    【讨论】:

    • 非常感谢您的回复。我一定会按照您的建议尝试并随时通知您。另外,作为一个测试,我尝试在主循环中应用瞬态来存储 $data = ob_get_clean();,滚动速度非常快,但由于瞬态是全局的,所以重复相同的产品。我想知道如何在调用主循环时制作独特的瞬态然后打印 $ 数据。关于将瞬态应用于打印所有 HTML 的主循环的任何见解?
    猜你喜欢
    • 1970-01-01
    • 2019-09-11
    • 2016-05-08
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多