Module and page caching for better performance

  • Posts: 36
  • Thank you received: 6
11 years 5 months ago #148625

I help run a hikashop store with over 4000 products and over 5000 categories. We have modules for best selling ever, best selling lately and recently added on the home page and on many other pages. While these modules don't need to be updated often, joomla module caching controls are primitive. When users are logged in, caching is disabled, so our return customers were getting the worst of bad performance.

I solved our speed problems by writing custom modules with caching support. The module contents are written to disk once a day (or course that is configurable) and then simply echoed the rest of the time. I accomplished this using the Sourcerer plugin. If there is interest in how I did this, I can provide more details or maybe package up an example.

Oh, and as the subject states, I did this for a couple pages with many (1000+) categories also.

Please Log in or Create an account to join the conversation.

  • Posts: 84290
  • Thank you received: 13691
  • MODERATOR
11 years 5 months ago #148652

That's interesting. Thank you for sharing your experience !

Please Log in or Create an account to join the conversation.

  • Posts: 31
  • Thank you received: 0
11 years 4 months ago #151138

Please provide details or package your stuff as a component/plugin. We would LOVE to use it! We have noticed pretty bad performance with many categories. We tried another caching component but it didn't work well with yootheme templates.

Please Log in or Create an account to join the conversation.

  • Posts: 36
  • Thank you received: 6
11 years 4 months ago #151436

So, for the modules I basically re-created the best selling and most recent ones in php. I use sourcerer within customHTML module to load my custom php. I call functions to check the cache and generate the module output if necessary. So, it is not a general solution at this point. I contacted the author of Advanced Module Manager, but he was not interested in added caching support. He said there are too many places it would not work. I told him that on the places it would work that it can be a life saver, but to no alas. I am considering creating something like loadposition plugin that would support caching. Not sure when I will get around to it.

For the caching category listings, I added code directly to view.html.php

	function display($tpl = null,$params=array()){
		$this->paramBase = HIKASHOP_COMPONENT.'.'.$this->getName();
		$function = $this->getLayout();
		$this->params = $params;

		$config =& hikashop_config();
		$this->assignRef('config',$config);
		$module = hikashop_get('helper.module');
		$module->initialize($this);
		$this->paramBase.='_'.$this->params->get('main_div_name');
    
    $cid = $id = JRequest::getInt("cid",$this->params->get('selectparentlisting'));
    if ($cid == "12" || $cid == "35")
    {
      $cache_id = "hika" . $cid;
      if (!ds_use_cache($cache_id ,strtotime('-1 hour')))
      {
        ob_start();

        if(method_exists($this,$function)) $this->$function();
        parent::display($tpl);
        
        $html = ob_get_clean();
        echo ($html);

        ds_create_cache($cache_id, $html);  
      }
    }
    else
    {
		  if(method_exists($this,$function)) $this->$function();
		  parent::display($tpl);
    }
}

The utility code looks like this
function ds_use_cache($cache_id, $ts=0) {
  $file = DS_CACHE.$cache_id;
  
  if(file_exists($file)){
    // and the file is readable
    if(is_readable($file)){
    
      $stale = false;
      $filets = filemtime($file);
      if ($ts) {
        if ($filets < $ts) {
          $stale = true;
        }
      }
      else if (date('Ymd', $filets) != date('Ymd')) {  
        $stale = true;
      }
    
      if ($stale == false) {
        // open the file for reading
        if($fp=@fopen($file,'r')){
          if(flock($fp, LOCK_SH))
          fpassthru($fp);
          flock($fp, LOCK_UN); 
          fclose($fp);
          return true;
        }
        fclose($fp);
      }
    }
  }
  return false;
}

function ds_create_cache($cache_id, $html)
{
  $file = DS_CACHE.$cache_id;
  if (file_exists($file)) {
    $fp=@fopen($file,'r+');
  } else {
    $fp=@fopen($file,'w');
  }
  if ($fp) {
    if(flock($fp, LOCK_EX)) {
      ftruncate($fp, 0);
      fwrite($fp,$html);
      flock($fp, LOCK_UN); 
    }
    fclose($fp);
  }
}

The following user(s) said Thank You: Xavier

Please Log in or Create an account to join the conversation.

Time to create page: 0.065 seconds
Powered by Kunena Forum