Littered all over the MODX Official Documentation are examples of Snippet calls using the uncacheable token "!". Furthermore, common, general misconceptions regarding what is, and what isn't, "dynamic" website content, contribute to the tragic under-utilization of MODX's powerful caching mechanisms.
Website performance is important, and can significantly affect the bottom line for your client, the website owner. By making a few simple changes to a site's Templates in MODX, noticeable performance gains can be achieved. But how do you know what to cache, what not to cache?
For practical purposes, we can divide up content based on when and where we expect it to change:
- Per Resource – typical examples include: navigation elements with active states based on what page is being viewed, listings of resources like a blogroll, as well as actual page content that is frequently updated.
- Per Request - typical examples include: tag/category filters, paginated lists, archive date and other time-based filters.
- Per User - typical examples include: form submission data, personalized content that requires the user to login, and member's only areas.
Per Resource Content
This type of content can sometimes mislead developers into calling MODX snippets uncacheable. Perhaps the output of the snippet is based on a TV Value that can change per Resource, or there are conditionals in the Template that change the output per Resource.
MODX, however, deals with this type of "dynamic" content out-of-the-box, with its standard partial-page caching. The way it works is, whenever a Resource is requested, MODX caches various elements that make up the page, so that next time the Resource is requested, it can assemble these php cache objects rather than query the database all over again.
Additionally, MODX does this on a per Resource basis. Nothing needs to be done to make this happen – it's like this by default. So it doesn't matter how similar, or different, one Resource is from another – each one gets its own set of cache objects.
Whenever a Resource is created, or edited (basically, whenever something is saved) the entire Resource cache is cleared, so that new cache objects will be regenerated based on any new content. This keeps elements like menus and listings up-to-date with fresh content. All of it is "cacheable" in MODX terms, meaning you never have to use the "!" token solely for this type of content.
Per Request Content
This one is a bit trickier, because there are legitimate cases where this type of content should be uncacheable, such as when an element is time-based. However, it depends on the resolution of the time period.
A blog archive, split into months or years, can be cached with an appropriate expires date, using tools like getCache.
Another example is pagination. Due to the fact that there is usually a finite number of pages to a given listing, the getPage Snippet actually caches a copy of the Resource, based on the requested page.
Note: even though the two Snippets mentioned above must themselves be called uncacheable with the "!" token, their action is to retrieve cached results if available. In other words, this is still "cacheable" content in MODX terms, only you must excercise a bit of ninjitsu.
Per User Content
This is the only type of content where, in the vast majority of cases, you want to call the related MODX tags uncacheable, with the "!" token. If you cache form submission data, for example, one user could be subject to data (probably private data) submitted by another user!
Another example would be content hidden behind a login. Presumably it's locked down because it's private. If you cache this content, one user could access another's content.
Suffice to say that the "!" token is very appropriate for this type of content. However, if a page is largely public, and cacheable, except for a tiny bit of personalization, like someone's name in the header for example, you could call this uncacheable content via AJAX and fully cache the rest of the page. Tricks like this are abundant, easy to implement, and can have a huge impact on performance and usability.
Cache is King
An overused cliche? Or critical mantra to live by?
Whatever you decide, hopefully this article helps a bit. Have questions, specific use cases, or ninja caching/peformance tips of your own? Please share them in the comments.