Улучшение скорости пользовательского бесконечного свитка - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть пользовательский бесконечный свиток, который отлично работает, но очень медленно.Вот скрипт, который обрабатывает запрос 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' );

Вот еще один пост с моим кратким описанием проблемы Улучшение производительности специально разработанного свитка .Вот код для 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

});

Есть ли способ использовать этот фильтр woocommerce_get_price_html вне сценария обработки запросов ajax (ga_infinite_scroll) как это очень дорого с точки зрения скорости использовать его в скрипте обработки ajax?Я попытался использовать переходные процессы в ga_show_price ().Как реализовать здесь другие типы кэширования, чтобы увеличить скорость бесконечной прокрутки?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

@ Предложения 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();
0 голосов
/ 09 февраля 2019

Таким образом, использование переходных процессов, вероятно, является лучшим «простым» ответом здесь без каких-либо серьезных переделок.Однако есть пара проблем с вашей ga_show_price() функцией.

Так что вы хотите всегда минимизировать количество вызовов базы данных или длинных длинных функций, которые вы вызываете из своего кода, чтобы ускорить процесс.

  1. Переходные процессы имеют глобальные имена.Таким образом, если вы используете что-то под названием sales_price для одного продукта, как только вы используете его для другого продукта, оно все равно будет сохранять стоимость предыдущего продукта.Вероятно, вам придется создать уникальное имя для всех ваших переходных процессов.Примерно так: set_transient('price_'.$product->getSKU(), ...).

  2. $variations = $product->get_children(); - Вы загружаете переменную $variations со всеми дочерними элементами продукта, что, вероятно, занимает довольно много времени и требуетнесколько звонков дб, тогда, если у вас уже есть переходный процесс для этого продукта, варианты никогда не используются !.Запускайте эту строку только в том случае, если у вас еще нет кэшированного значения для продукта.

  3. Меньшая проблема, но вы вызываете get_transient дважды каждый раз, когда у вас есть кэшированное значение.Один раз, чтобы проверить, что это не ложь, а затем снова, чтобы фактически получить значение.Может показаться мелочью, но если у вас загружено более 100 продуктов, это складывается.

Мне нравится делать это с моими переходными процессами:

 $value = get_transient('something');
 if ($value === false)
 {
    $value = some_long_calculation();
    set_transient('something', $value, ...);
 }

 //Now use $value here.
Стань еще более агрессивным с кешированием.Как часто товары меняются с продажи на не продажи?Не чаще одного раза в день?Затем просто кешируйте весь расчет функции вместо того, чтобы сначала проверить, имеет ли она продажную цену или обычную цену.

Предупреждение: у переходных процессов есть максимальная длина для их имен и значений, поэтому вы не можете хранить их тожемного в них.Кроме того, они предназначены только для хранения нескольких значений, а не цены для каждого продукта в вашей системе.

Если это так, то вам, вероятно, лучше подумать о кэшировании значения в настраиваемом поле для каждого продукта?Вы можете прикрепить крючки так, чтобы каждый раз, когда продукт обновлялся, он автоматически обновлял пользовательское поле рассчитанной цены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...