page caching your whole app

Courtenay : December 16th, 2005

The problem: we had to launch a site on a box with limited resources -- we were expecting at least a few 100k hits/day, and weren't confident of rails' ability to scale. So here's what we did: we turned on page caching (humorously referred to as "paching") for everything.. however.. the page had a box which contained a login/password form, which changed to "logged in as ... you can (edit profile :: edit articles :: blah blah)" when they logged in. So, how to maintain this dynamicity without sacrificing the page caching? There are many ways to do this; I'll be showing you the page rewriting method; but technoweenie will be presenting his awesome ajax-and-behavior technique. update[1]: thanks to technoweenie for some additional examples and code. update[2]: you can now view a live-action demo here Based on my previous experience here (I had developed the original "posted x minutes ago" in JS for typo) here's how we solved it: h2. 1. strip da erb first, remove all user-referencing erb code from the views. h2. 2. rewrite the login-module box .. so it shows both the login form, and the user-info form like this:

h2. 3. create the js action note: this can be done with RJS, but it's not in 1.0, so I'm leaving this in raw JS for now.. Note that this action isn't cached; however; with a bit of extra work this could be done..

var User = {
  activate: function() {
    $('username').innerHTML = User.name;
    Element.hide('unauthorized');
    Element.show('authorized');
  },
  name: "<%= @current_user.name %>"
}
then you can additionally create an array of <LI> containing the user actions (depending on role), and you dynamically insert those too, into the user__tasks UL include this action with
in the header if you want to page cache the JS file, too, you can do something like:

Note that this doesn't wait for page onload; it runs immediately, so you have to make sure you're not in a <table>block (or it'll error in IE). This also means the page appears accurate with no delay. In theory, you could even decouple this view from any controller action; just store the username and some permissions-triggering code in cookies, and do all the work with JS. however, we found that a simple controller-based JS action easily sustains about 40 req/second, which is 144k hits/hour, and plenty enough for us.

Sorry, comments are closed for this article.