Cache Block is a plugin for Movable Type that can dramatically speed up publishing by caching blocks of built template code. Cache Block is very flexible, enabling you to cache an entire page, a small template snippet, a template module, a sidebar widget, and entire sidebar, etc. Each block can be set to expire after a certain duration -- some blocks you may want to cache for 5 minutes, others for hours, or even days. When used wisely, the result is significantly faster publishing times and faster comment-posting.

Cache Block on ReadWriteWeb

ReadWriteWeb is a very popular technology blog with many entries and comments. And with over 130 front page Diggs and counting, ReadWriteWeb gets a lot of traffic. With the goal of speeding up publishing and comment posting, I recently implemented Cache Block on ReadWriteWeb. Combined with other optimizations, Cache Block helped to significantly improve publishing speed and now comments post much faster. This is one example of Cache Block being used on a live, busy site.

How It Works

For each page that is published by Movable Type, a large number of template tags are evaluated by the system, which often requires many database lookups. The Cache Block plugin strives to reduce those database lookups by caching groups of template code that has already been evaluated. For example, suppose you decided to cache your entire sidebar. The first time MT publishes that sidebar, it will do many database lookups to generate lists of recent entries, comments, lists of archives and tags, etc. After that, the Cache Block plugin will take all of that sidebar HTML and save it in the cache. The next time MT needs to publish your sidebar, it will find it in the cache, so it will skip the evaluation and related database lookups for the entire sidebar, and simply fetch the pre-built sidebar from the cache. This can speed up the process a lot. Imagine if you are trying to publish a 1000 page site, and each of those pages includes the sidebar!

Behind the scenes, Cache Block checks to see if memcached is available and enabled. If it is, CacheBlock will stores blocks using memcached, which is very fast. BUT, you don't need to have memcached! If memcached is not available, Cache Block will simply store the block in the database. As such, it will still require a database lookup to retrieve it from the cache, but you can save dozens or even hundreds of database lookups by caching significant segments of built template code, by replacing them with a single lookup to the cache. Even without memcached, Cache Block can dramatically speed up publishing.

Template Tags

Cache Block has just one template tag:

  • <MTCacheBlock> - This container tag should be wrapped around the block that you want to cache. Everything between the opening <:MTCacheBlock> and the closing </MTCacheBlock> will be saved as a single block in the cache. There are several arguments for this tag:
    • key - (Required) The key argument represents the cache key, a unique identifier for the cache block. Each block should have unique key. Note that keys are not namespaced on a per-blog basis -- meaning that a key of "foo" used in one blog will overwrite a key of "foo" on another blog.
    • expiry - (Required) The number of minutes that the block will be stored in the cache. Longer expiry times will result in more speed improvements, but the ideal expiry depends greatly on the content being cached and the volume of activity of your site.
    • refresh - (Optional) This argument is designed for temporary use only. Adding refresh=1 will force an update of the cache. In other words, with this argument, blocks will never be fetched from the cache. This argument is useful when you are making design changes to your templates, and you want to refresh the cache block so that you can view your changes on your site. After your template editing is complete, remember to remove the refresh=1 from all MTCacheBlock tags, so you can once again reap the benefits of the cache.

Cache Block Expiry

For Cache Block stored in the database, blocks are expired by a scheduled task that is set to run once per minute, at most. To ensure timely expiry of cache blocks, I strongly recommend that you set up a cron job to run the /tools/run-periodic-tasks script on a regular frequency that is consistent with your caching strategy. Click here for more information about scheduled tasks and setting up a cron job.

Cache Block Pro

Cache Block Pro includes the same powerful caching features, and adds powerful administration tools to facilitate further optimization and management of your Cache Blocks. Features include:

  • Flush Entire Cache - This useful function provides a quick way to flush your entire cache. Normally, you wouldn't want to do this, but during a redesign of your site, this one can come in handy.
  • Cache Blocks Widget - When you are editing a template, this widget will appear on the right side of the page, listing the Cache Blocks used by the template. When possible, listed blocks will have a "flush" link next to them so you can flush a single block easily. You can also click on the linked names of the blocks to view the contents of the Cache Block.
  • View All Cache Blocks - Use this feature to view a list of all Cache Blocks on the system, including the expiry date of each. Note that this feature is not currently available if you are using memcached.
  • Edit Cache Block - Manually edit the contents of specific Cache Blocks and change the expiry dates as desired.
  • View Rendered Block - From the Edit Cache Block screen, you can view the rendered HTML of the block. Instead of view the built HTML source, this will display thye block as it would be shown in the browser (in most cases, without applying your external styles)

Requirements

  • MT3.3+

Note: The Pro features described above require MT4.01 or higher.

Installation

  1. Upload the contents of the 'plugins' folder to the 'plugins' directory of your MT installation (usually /cgi-bin/mt/plugins/)
  2. Start using the >MTCacheBlock> tag in your templates, as described above.

Click here for Cache Block Examples.

Get Cache Block Pro

Commercial License for 1 to 10 blogs - $97

Blog Network License for 10+ blogs - $249

Personal License for 1 to 4 blogs - $33

Get Cache Block

Cache Block is free for personal or evaluation use.

Download Now

Download Now
Downloads: 400

Membership required, please sign-in or register:

As always, comments, questions, and suggestions are welcome.

The key to using the Cache Block plugin to speed up publishing is to cache items that may require a lot of resources or database queries to build, that don't strictly need to be updated on every single page build. One thing to keep in mind when planning your caching strategy, is that the posting of new entries and the posting of comments will trigger a automatic rebuild/re-publish of multiple pages of your site. For example, when someone posts a comment, the entry page for that comment gets rebuilt, as does the category pages for all categories of that entry, any date-based archives containing the entry, author archives for the entry author, and all index templates that are set to "rebuild with indexes". As such, the frequency of comments can play a major role in how much publishing activity happens on your site.

Some ideas for Cache Blocks:

  • cache your entire sidebar for 60 minutes
  • cache your entire "Archive Index" for 1440 minutes (a full day)
  • cache your feeds for 60 minutes (so they won't get built on every comment)
  • cache entry summaries and comment detail modules to speed page builds with many entries or comments
  • cache individual sidebar widgets that don't need to be updated frequently
Example: Cache Your Sidebar

If you are using MT4 default templates, you can cache your sidebar as shown below. In this example, the sidebar is cached for 60 minutes.

<MTCacheBlock key="blog1_footer" expiry="60">
<$MTInclude module="Footer"$>
</MTCacheBlock>

Let's assume the above code is on your "Main Index" template. The existing MTInclude is simply wrapped inside an MTCacheBlock container. Note that doing it thos way will only check the cache when the Main Index template is built. But most sites have the same sidebar displayed on multiple pages of the site. If this is true for your site, you can gain even more benefit from wrapping each of those MTInclude blocks, using the same cache key. But be careful -- many sites have unique sidebars for each archive page (entry, category, etc.) -- in such cases you won't want to pull the same "Main Index" sidebar.

Looking at the above example, you may be wondering whether it would be easier to simply place the MTCacheBlock tags inside the "Footer" template module. That way, you wouldn't have to repeat the process for each template that shares the same sidebar. There are two reasons why this is not a good idea:

  1. As a general rule when caching the contents of template modules, you will get more speed gains by placing the MTCacheBlock tags around the MTInclude statement, rather than inside the module itself. The reason is that if MT finds the block in the cache, it won't even bother trying to load and evaluate the included Template Module, which requires a database lookup by itself. In short, you can save at least one database lookup by wrapping the MTInclude tag instead.
  2. The second reason -- at least in this specific example -- is that the default "Footer" module is included for all pages for the site, and it contains some conditional code that creates different sidebars for different pages. As noted above, the sidebar for the Main Index may be different from the sidebar that appears on an Entry archive page. In such case, you need to be very careful. If you placed the MTCacheBlock tags inside the Footer module, then every page would have the exact same sidebar, and that would be the first sidebar that was built and saved in the cache. For example, suppose the first page to publish was one of you Entry Archives. MT would built the special sidebar for that entry ("This page contains a single entry from....", etc.) and save that in the cache with the key "blog1_footer". And then MT would publish your Main Index and MT will check the cache for "blog1_footer" and it will grab that Cache Block and place it in your Main Index. You should always be careful when caching block that include condition logic. For similar reasons, you should also be careful when caching block that are inside looping container tags (see below).

Example: Caching the 'Comment Detail' Module for each Comment

Suppose you have a site that gets a lot of comments. Some of your entries get over 100 comments. Every time a new comment gets added, MT will re-publish your entry page and build the HTML for every one of those 100+ comments. Consider that once a comment has been posted, it rarely changes (unless you edit the comment for some reason). As such it is safe to cache the HTML for each individual comment, so MT won't have to evaluate those template tags for each comment. You can do so as follow, in your "Comments" template module:

<MTSetVarBlock name="comment_cache_key">comment_detail_<mt:CommentID></MTSetVarBlock>
<MTCacheBlock key="$comment_cache_key" expiry="120">
<$MTInclude module="Comment Detail"$>
</MTCacheBlock>

Notice that this example is a little different. Because the MTInclude tag is inside the MTComments container, which is repeated for every comment, we can't use the same cache key for every comment. We need to make sure that we use a unique cache key for each comment. We do this by using MTSetVarBlock to create a variable that represent a unique key. In this case, I chose comment_detail_<mt:CommentID> which will be unique because it includes the commentID number. Once we have saved this unique key in the "comment_cache_key" variable, we can then use that as the key by specifying key="$comment_cache_key" (note the dollar sign to indicate that we are using a variable).

The examples above are just two of the many ways that you can use Cache Block to speed up your MT publishing. Since each site is different in terms of templates, posting activity, traffic, etc., different techniques may work better for different sites.