|Using caching in Joomla extensions|
|Od Klas Berlič|
There is much confusion about Joomla 1.5 cache capabilities, it's variations and possible ways to implement it in extensions. Incomplete or missing documentation is the first to blame, but the fact that even core extensions didn't use cache until Joomla 1.5.15 or that they stop working properly when cache is turned on (related items module - fixed in upcomming 1.5.16 release, mainmenu etc.) doesn't help either.
I hope the following information will help you create another excellent extension that will not only do it's job, but will also be able to do it fast and scale well under a heavy load.
Give me speed! (Why bother by using cache at all?)
On a typical web site the same content gets displayed over and over again to anyone who visits your site. Without cache everything has to be generated for each and every page view - but caching can speed up this process by storing some or all of the information your code generates in a cache object and return it when next visitor requests the same page or particular piece of information.
Joomla caching options explained - short developers guide
There are few basic cache types in Joomla - page cache, module/component view cache, function cache and output cache . As this guide is aimed at extension developers, let us first take a brief look at page cache and then focus on our main subject - other cache types.
As you might have figured out from it's descriptive name, page cache takes snapshots of entire pages including everything - component, modules, plugins and template. On first visit it stores the entire page and all following request for the same URL are served by cached version, until this cached copy expires. As the whole page is basically frozen in it's initial state this is the widest and the least flexible approach of all caching options.
Page cache is enabled by core system plugin and so it lies in the site administrator's domain whether to use it or not.
component View caching and module caching
This two represent a group as they work in a similar way - they create a static copy of complete extension's output. But with an important difference - due to the component's MVC architecture it is possible to turn view caching off where needed, while modules are deprived of such an option - core module caching can only be set to on or off for all instances and cannot be controlled from within the module. All module scripts are run only once (until it's cache expires), while components controller gets allways executed and view cache can be managed from inthere.
This code turns on view caching in component's controller's display() method:
and off (which is also default):
Module cache on the other hand is controlled by the module's XML file parameters:
While this cache type performs well in the speed terms, it practically disables any user<->extension<->framework interaction until a cached copy has expired and that is why it's not suitable for any components or modules that react to user actions or render frequently changing content.
Components can work around this by disabling view cache when necessary (e.g. on pages with forms) and enabling it where they render content that changes less frequently (articles are nice example of this, once written they stay pretty much the same), the only way to use cache in modules that change from page to page (e.g. related items module, module that shows pictures based on Itemid etc.) is to disable core module cache in XML and create it's own cache method. By doing this we ensure that at least some small part of the module gets executed and can be used to control caching - functionally similar to component's controller.
In addition to the blocking of interactive and dynamic functions, view/module cache also has another, often missed, side effect - as it's cached copy includes only module's or component's own output and it's interaction with the rest of the framework is blocked - any external file that is called by using Joomla's methods like $document->addStyleSheet($url); or $document->addScript($url); won't get included when visitor is served by the cached copy.
To come around this limitations few workarounds were implemented, but they represent a bit of catch22 - they require computing power to work and so diminish the effect of caching. I would recommend that when your extension performs dynamic operations simply avoid view cache and replace it with function cache.
Function caching enables us to differentiate between various parts of the extension and cache only those parts that are cacheable, while keeping dynamic parts uncached. Often it is useful to cache model methods and keep views uncached. That way expensive queries or similar operations are performed only once to create pool of data which is then futher manipulated (sorting, pagination, calculations etc.) inside the view - this operations are hence executed much quicker than if database query or even remote XML connection has to be run for every request.
Code without function caching:
And with it:
If you would like to call instantiated method (versus the static one above) and pass it parameters:
(parameters can be passed in the same way when using static function above)
If you would like to take control of component's caching out of administrators hands or just tweak some of it's parameters like lifetime, you can manually set any of the $options (that are set to their configuration settings in the example) bellow:
Some additional notes
Closer look at Joomla 1.5 cache drivers reveals that all drivers except file cache are only half implemented - e.g. clean methods are just dummy placeholders. so I wouldn't recommend using them - they might work for some simple tasks, but anything that requires full functionality will fail.