Improving the speed of a custom infinite scroll

前端 未结 2 1171
慢半拍i
慢半拍i 2021-01-25 20:07

I have a custom infinite scroll that is working perfectly but it\'s really slow. Here is the script that handles the ajax request:-

function ga_infinite_scroll()         


        
相关标签:
2条回答
  • 2021-01-25 20:42

    @Mikepote's suggestions for ga_price increased the speed but editing the main product loop based on unique transient increased speed more. I hereby attach my code:-

      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 讨论(0)
  • 2021-01-25 20:44

    So using transients is probably the best "simple" answer here without doing some major rework. However there's a couple issues with your ga_show_price() function.

    So you want to always minimise the amount of database calls or long lengthy functions you call from your code to make things faster.

    1. Transients have GLOBAL names. So if you use something called sales_price for one product, as soon as you use it for another product it will still hold the value of the previous product. What you'll probably have to do is generate a unique name for all your transients. Something like: set_transient('price_'.$product->getSKU(), ...).

    2. $variations = $product->get_children(); - You're loading the $variations variable with all the children of the product, which probably takes quite a while and involves quite a few db calls, then if you already have a transient for this product, the variations are never used!. Only run this line if you dont already have a cached value for the product.

    3. A smaller issue, but you are calling get_transient twice every time you have a cached value. Once to check that it's not false, and then again to actually retrieve the value. Might seem like a small thing, but if you have 100+ products loading in, it adds up.

    I like to do this with my transients:

     $value = get_transient('something');
     if ($value === false)
     {
        $value = some_long_calculation();
        set_transient('something', $value, ...);
     }
    
     //Now use $value here.
    
    1. Get even more aggressive with your caching. How often do items change from being on sale to not being on sale? Not more than once a day? Then just cache the entire function's calculation instead of first checking if it has a sales price or regular price.

    A word of warning: Transients have a maximum length for their names and values so you cant store too much in them. Also they're designed for only storing a few values, not a price for every single product in your system.

    If that is the case you're probably better off thinking about caching the value in a custom field for each product? You could attach hooks so that every time the product is updated, it updates the calculated price custom field automatically.

    0 讨论(0)
提交回复
热议问题