page caching with 'interesting' routes.rb


I recently came onto a project with a large code base. I'm attempting
to speed it up a bit by page caching a controller action that does
most of the hard work. This "Browse#index" action handles the home
page in addition to browsing various content types :

  BrowseController#index <= <site>/

browsing examples:

  BrowseController#index <= <site>/browse/atricle-category-name
  BrowseController#index <= <site>/browse/product-review/cat-name
  BrowseController#index <= <site>/browse//etc

The routes for this are as follows:

  map.default_route '', :controller => "browse"
  map.connect "browse/*url_components", :controller => "browse",
:action => "index"

I added caching like so:

  class BrowseController
    caches_page :index

This results in caching '/' with no url_components, nothing else is cached.

I believe I know *why* this doesn't work (the route doesn't play nice
with url_for), but not an easy work around.

While I'm looking at refactoring this code into several controllers, I
do not know the code base well enough to do that quickly and we're
trying for the moment to meet a deadline. Any ideas?



I have a lot more experience with action caching, which can get you a
lot of performance improvement for less effort than page caching in
complex situations. I am biased, since I wrote the action_cache plugin
which, among other things, allows you to decide which paramaters you
care about for your cache key, which is exactly the problem with your
swiss-army index action.

Take a look on Ben's plugin site - for more info, and
my blog for a number of posts on how to use various features -

If you're interested in going this route(!), I can go into specifics on
how to make it work for your situation.

Tom, thanks for the reply. I've investigated your plugin previously
(it's very cool) and check your blog now and again (go seahawks). My
'problem' with action caching is that while it's often good enough,
you gain an order of magnitude when you avoid hitting rails. This is
good for the user (pages are snappy) and good for the wallet (machines
do cost money).

Personally, I'm actually thinking more these days about the potential
benefits of "inverse fragment caching" (just made that up). That is,
cache most pages everything with page caching and use ajax to load
any fragments that are truly dynamic, such as a header that prints
'log in' for some and 'log out' for others. I'll post more on this
if/when I really prove it out.



Someone reads my blog - cool!

I've found that almost all non-trivial web sites are going to have
problems with page caching, for exactly the reason you mention. There
always seems to be something you put on the page that needs to change
based on some condition other than the url - logged in state is the
obvious one. Rails doesn't do this well once you get to these

I think having Ajaxy things to get parts of the page can work, but if
you have more than one of them per page, then the load on the server
may end up being more that a single request that is in the action

If you're on a deadline, I would put in action caching (since it's
easier and gets an order of magnitude better perf than nothing), and
refactor the code to make page caching easier in the future.