SilverStripe's partial caching is build as a wrapper around Zend Cache and works something like this: the first time a page is displayed, designated blocks of template are parsed into cachefiles that are then included in the template the next time round, until either the cachefile's TTL expires or some other condition is met. This can increase speed and performance significantly!
More info can be found in the header of the SS_Cache class (sapphire/cache/Cache.php).
To cache a block of template, use a cacheblock. This example will cache the block for 10 minutes, which is the default TTL:
<% cached %> <!-- some complex parsing and calculating --> <% end_cached %>
Beware of one thing: cached blocks can be nested, but they cannot be placed within <% if %> or <% control %> blocks!
A cache block will accept an unlimited set of (optional) comma-separated parameters. The first parameter should be a unique identifier. The next params can be variables or function-calls. SilverStripe then uses the combination of these values to build a key that will be used to identify and name the cachefile. If no parameters are given, like in the example above, the cachefile will still have it's unique key, since the name of the template and the sha1 content of the cached block will be added as well.
So every time one of these values changes - including the contents of the cached block itself, the key changes as wel, rendering the cachefile invalid. If, however, there are no params, or they never change, the cachefile will still expire after its TTL is reached. In the following example the cachefile will either expire after 10 minutes (default) or if some custom Page_Controller method CheckSomeValue() returns something new - whatever comes first:
<% cached 'myIdentifier', CheckSomeValue %> <!-- some complex parsing and calculating --> <% end_cached %>
Note: I've experimented with using the same identifier for multiple cached blocks, and it didn't seem to matter at all, not even when I didn't use any other params. So???
If you created a silverstripe-cache directory in your site root (which I would recommend), you'll find them in the silverstripe-cache/cache/ directory. There'll be 2 files for each cached block, where the internal-metadatas version contains information like the TTL:
Note: Identifier again: I feel that it should somehow be part of the cachefile name, to easily identify it. but I'm not sure...
Place the following in your site's _config.php file:
SS_Cache::set_cache_lifetime($for = 'any', $lifetime = 3600, $priority = 100);
This will set the TTL to 1 hour (3600 seconds) for 'any' Cache object in existence. The setting with the highest priority will be used. Default it is set to -1. In theory you could have multiple Cache objects, all with their own TTL, but SilverStripe uses only the one, called 'cacheblock' (you'll see it as part of the filename above). So you can't easily define different TTL's for different cached blocks....
There are two conditionals that you can use to determine if a block should or should not use its cachefile at any given situation. Here, depending on whether the user is logged-in::
<!-- don't cache if the current user is logged-in --> <% cached unless CurrentUser %> ... <!-- cache only if the current user is logged-in --> <% cached if CurrentUser %> ...
You can exclude a template block within a cacheblock from being caching by using an uncached block. This example will create 2 different cachefiles (or 4 if you will) for the bit before- and the bit after the uncached block:
<% cached 'complexRoutine' %> $ComplexStuff <% uncached %> $somethingSimpleAndDynamic <% end_uncached %> $MoreComplexStuf <% end_cached %>
Even if you were to cache an entire page, still lots of queries will be performed - which you can see by adding ?showqueries=1 to the url. Most are about Members and Groups, but you'll also see has_one relations for the current page being retreived - whether we use them or not!
Most times, though, it's not so much the queries that slow the site down. More often it's the amount of processing and template parsing that's being done...
I would think it's definitely not a good idea to cache blocks of fairly straightforward template, and then use a complex set of methods to check if the cache should yes or no be expired. The other way around however... So you need to know where the bottlenecks are.
One way to find out about them is to add ?debug_profile=1 to the url. This will tell you where the time goes. One of the bigger consumers is SSViewer::process() - that's where the templates are processed, so here you should at least gain some profit...
More about these URL Variable Tools you'll find here.