0

Can someone point me to some example code on how best to do caching while loading up the dynamic parts of a page using javascript?

My canonical example involves a page where nothing ever changes other than the user's logged in status and username at the top of the page. Changing this text through jQuery and an ajax request is easy enough, but since I'm doing it on $(document).ready(), if you look quickly, you can see the page load with something like "Click Here to Login" before the ajax request fires and updates that section of the page.

Edit for clarification:

If I cache the entire page, the following happens.

  1. User A requests the page
  2. Page is not cached, so application generates html with "Hi User A" in the upper right corner
  3. User B requests the page
  4. Page is cached, so application serves it us as-is -- including the "Hi User A" bit <- This is the part that I want to dynamically update.

Ideally, at step 2, the page would get cached without the "Hi User A" bit, so that when someone requests the page, I make a simple ajax request to get the greeting and then shove it into the dom.

I'm assuming javascript is the way to go, but I'm thinking there has to be a better way than to wait for $(document).ready() such that the page renders more naturally.

If it matters (though I don't think it should, as a solution that applies to static html would also work for what I'm doing), I'm using rails 2.3.x and jQuery.

jerhinesmith
  • 15,214
  • 17
  • 62
  • 89
  • It would be far nicer to do this kind of manipulation on the server rather than in Javascript. – lonesomeday Dec 22 '10 at 21:10
  • Of course it would, but that would mean I'm regenerating the entire page for each request. I'm trying to **avoid** that. :) – jerhinesmith Dec 22 '10 at 21:12
  • @jerhinesmith No, I would cache fragments of the page. Or cache the whole page only for logged out users. – lonesomeday Dec 22 '10 at 21:13
  • I thought about going that route. It just feels weird to be caching fragments when really it's only a single line that changes. I'd be jumping through hoops to cache all of the fragments around that one small div. Caching for only logged out users is an interesting idea. – jerhinesmith Dec 22 '10 at 21:20
  • you could place a `` right under said element if you wish to fire before the entire DOM is ready. – subhaze Dec 22 '10 at 21:22
  • @subhaze, that sounds like what I'm looking for. Can you find any example of someone doing this properly? For example, does the script itself emit the html? Or does it generate the necessary html and then inject it into the dom? I'm thinking that if it emitted the html, it would get me all of the way there (as it wouldn't require the document to be "ready"). – jerhinesmith Dec 22 '10 at 21:27
  • @jerhinesmith like this? http://www.jsfiddle.net/subhaze/MN5mk/ – subhaze Dec 22 '10 at 21:31
  • @subhaze Yes! Exactly like that! Do you know if it's possible for `document.write` to pull in the contents of a file? Or do you have to do it all through string manipulation? – jerhinesmith Dec 22 '10 at 21:41
  • @jerhinesmith: It will write out a string to the document. One thing to note though if you're using Ajax this might not be the best solution. If you know your values then this should be safe. However, if you're waiting on a Ajax response there will be a delay and most likely all of the page will be replaced by the output of `document.write`. Here's a bit of an alternative for Ajax request. There's still a delay, depending on time it takes to get a response, but will fire a lot sooner than document ready would if it's a large page. http://www.jsfiddle.net/subhaze/MN5mk/3/ – subhaze Dec 22 '10 at 21:52

2 Answers2

1

I would load the user status initially in the main page on the server, using the same thing that generates the AJAX response. Then when the user changes the status, update it using AJAX client-side.

This way, the initial page has the correct status but can still change when the user performs an action.

Pretend the method getStatus() generates the correct HTML for whatever state the user is in. On the page, I would have a <div> that contains this information. Server-side, call getStatus() (using PHP for example purposes):

<div id="status"><?php =getStatus() ?></div>

Then have your AJAX request return getStatus() and update the <div id="status"> contents.

zsalzbank
  • 9,685
  • 1
  • 26
  • 39
  • That's kind of what I'm doing now. The problem is that the status doesn't get changed until the document is ready -- meaning if the rendering takes even a half second, you can see the cached status briefly before the javascript updates it. Does that make sense? – jerhinesmith Dec 22 '10 at 21:17
  • then that is not what you are doing. the `getStatus()` should be called server-side before anything on the page is displayed. the browser would just interpret it as normal HTML, not anything that javascript would have to touch. – zsalzbank Dec 22 '10 at 21:19
  • No, `getStatus()` wouldn't be called if you're just serving up an html page. It would only get called if you're serving up a dynamic page (via php/rails/etc) ... unless I'm not understanding you correctly. – jerhinesmith Dec 22 '10 at 21:26
  • Yes... but it is still server side. If you request `index.php`, it does not make an additional call to `status.php` for the user status the first time. The `getStatus()` is inside `index.php` and then when the status changes via login or whatever, the AJAX calls it and changes via `status.php`. – zsalzbank Dec 22 '10 at 21:49
0

Aha! There's a railscast that does exactly what I want!

Rails-y goodness can be found here: http://railscasts.com/episodes/169-dynamic-page-caching

jerhinesmith
  • 15,214
  • 17
  • 62
  • 89