Mambo - Simple full site caching for dramatic speed gain
Marc
As I've described just a short while ago, I was working on speed issues with my Mambo (ver. 4.5.1) based site icq-4u.com. In addition to the caching of the site's download charts I've also thought about adding full site caching. Of course this step requires a fitting scenario since a full site cache freezes most of the dynamic content modules one might be using.
What I wanted was a pretty fast frontpage, but even with Mambo's native caching enabled it was still somewhat slow. The page generation time that I was displaying on my sites footer (which by the way is far from precise if you only include it in the template file) always stayed around the 0.7 mark which annoyed me. Of course 0.7 does not sound so slow, but considering that that specific duration wasn't accurate (try twice as much, when timing correctly prior to template initiation) and that caching was supposedly already enabled I was a litte bit disappointed.
Having looked into Mambo's caching function already I knew what was there and what was feasible, so I studied Mambo's index.php to find a fitting spot for a cache inclusion. These are the steps I did:
As you can see in step 1 , I've added cache activation pretty early and just after the user athentication. The modifcation will only apply for pages that are either the part of the remository component or the frontpage and only if the user's id is unspecified i.e. the user is unregistered. The cookie check is necessary to avoid sync issues with the SMF bridge for Mambo which I use. After that I start the caching with random identifier variables. And since we open an if here, we'll have to close it again. That's what the seconds code block in step 1 is about.
In step 2 we add functionality for a second caching method to Mambo's core. Mambo's caching component originally came from PEAR but only includes the call-function which allows caching of a function output, but not caching of a certain segment in the script which we intend to do. To be able to differ between both methods, we're adding the &getCacheAlt() function to the core. That's also the function which we call earlier in step 1.
Finally, in step 3 we add the additional PEAR function that is missing in Mambo.
Note: If you have Mambo's gzip function enabled, you might get a blank page upon the first page request and initial cache file generation. I use apache's gzip functionality which works great and also allows me to cache my CSS files.
- In index.php around line 250 add like this:
PHP:
-
// marc 05.01.2007 22:37
-
// cache activation
-
// INSERT BEGINNING
-
$maincache = &mosCache::getCacheAlt( 'com_main' );
-
$cache_idle = true;
-
if(!($maincache->start($my->id.'_'.$Itemid.'_'.$option.'_'.$task.'_'.$_SERVER[REQUEST_URI], 'com_main', $cache_idle))) {
-
// INSERT END
-
-
// gets template for page
-
$cur_template = $mainframe->getTemplate();
-
require_once( $configuration->rootPath().'/includes/frontend.php' );
-
require_once( $configuration->rootPath().'/includes/mambo.php' );
-
require_once ($configuration->rootPath().'/includes/mambofunc.php');
-
require_once ($configuration->rootPath().'/includes/mamboHTML.php');
-
...
Now scroll all the way down and add these two lines:
PHP:
-
...
-
// marc 05.01.2007 22:37
-
// INSERT BEGIN
-
$maincache->end($cache_idle);
-
}
-
// INSERT END
-
-
}
-
// displays queries performed for page
-
...
- In include/core.clases.php find line ~2675 and right after the &getCache function add this additional function:
PHP:
-
...
-
function &getCache( $group='' ) {
-
$mosConfig_absolute_path = mamboCore::get('mosConfig_absolute_path');
-
require_once($mosConfig_absolute_path.'/includes/Cache/Lite/Function.php');
-
$path = mamboCore::get('mosConfig_cachepath');
-
$caching = mamboCore::get('mosConfig_caching');
-
$time = mamboCore::get('mosConfig_cachetime');
-
'cacheDir' => "$path/",
-
'caching' => $caching,
-
'defaultGroup' => $group,
-
'lifeTime' => $time
-
);
-
$cache =& new Cache_Lite_Function( $options );
-
return $cache;
-
}
-
-
// marc 05.01.2007 22:37
-
// INSERT BEGIN
-
function &getCacheAlt( $group='' ) {
-
$mosConfig_absolute_path = mamboCore::get('mosConfig_absolute_path');
-
require_once($mosConfig_absolute_path.'/includes/Cache/Lite/Output.php');
-
$path = mamboCore::get('mosConfig_cachepath');
-
$caching = mamboCore::get('mosConfig_caching');
-
$time = mamboCore::get('mosConfig_cachetime');
-
'cacheDir' => "$path/",
-
'caching' => $caching,
-
'defaultGroup' => $group,
-
'lifeTime' => $time
-
);
-
$cache =& new Cache_Lite_Output( $options );
-
return $cache;
-
}
-
// INSERT END
-
...
- Replace includes/Cache/Lite/Output.php with this
PHP:
-
/**
-
* This class extends Cache_Lite and uses output buffering to get the data to cache.
-
*
-
* There are some examples in the 'docs/examples' file
-
* Technical choices are described in the 'docs/technical' file
-
*
-
* @package Cache_Lite
-
* @version $Id: Output.php,v 1.1 2005/07/22 01:57:13 eddieajau Exp $
-
* @author Fabien MARTY <fab@php.net>
-
*/
-
/** ensure this file is being included by a parent file */
-
require_once( $mosConfig_absolute_path . '/includes/Cache/Lite.php' );class Cache_Lite_Output extends Cache_Lite
-
{
-
// --- Public methods ---
-
/**
-
* Constructor
-
*
-
* $options is an assoc. To have a look at availables options,
-
* see the constructor of the Cache_Lite class in 'Cache_Lite.php'
-
*
-
* @param array $options options
-
* @access public
-
*/
-
function Cache_Lite_Output($options)
-
{
-
$this->Cache_Lite($options);
-
}
-
-
/**
-
* Start the cache
-
*
-
* @param string $id cache id
-
* @param string $group name of the cache group
-
* @return boolean true if the cache is hit (false else)
-
* @access public
-
*/
-
function start($id, $group = 'default', $idle = true)
-
{
-
if($idle == false){
-
$data = $this->get($id, $group);
-
if ($data !== false) {
-
return true;
-
} else {
-
return false;
-
}
-
} return false;
-
}
-
-
/**
-
* Stop the cache
-
*
-
* @access public
-
*/
-
{
-
if($idle == false) {
-
$this->save($data, $this->_id, $this->_group);
-
}
-
}
-
}
-
?>
To be on the safe side you should always make backups before playing around with files ;-)
Since my remository and frontpage don't have a lot of dynamic content, I was able to set my cache time to one hour and have experienced a great gain of speed. Only one particular adsense adveritising block for which I serve user specific ads (location and language) had to be "oursourced" and is now being called via javascript.
Have fun!
