tags:

views:

112

answers:

7

I would like to utilize caching on a couple pages:

  1. individual blog pages
  2. index.php

However, after devising my system, I realized that the headers of my pages change according to state very slightly (aka, it says something like "Hello, [email protected]" if you are signed in). I therefore want to make sure that it doesn't accidentally display the wrong username or email up top.

It's a shame that such a small thing that I would like to NOT be cached on a page should force me to cache nothing on my site at all.

How can I get around this?

+7  A: 

You'll want to think about WHY you want to do caching. Caching is an optimisation and as such, should only be done if necessary.

If you aren't sure it's necessary, go back and do some research to make sure. This will involve performance testing on production-grade hardware on your test lab.

Once you're sure it is necessary, then you will know how much improvement you need. You can consider caching just PARTS of pages - this will be less efficient on the front-end and caching layer than caching complete pages, but may take more load off the back-end as you will get a higher cache hit rate.

Consider a page which has a personalised element (say, Hello Johnnie) and a part which is expensive to compute but changes relatively infrequently and is the same for all users - say some stock prices.

You can cache the stock prices part of the page for (say) 5 minutes and generate the personalised part of the page each time. That way you don't hit your back end for stock prices and can still show the right page to the right people.

Most companies find that generating the front-end is quite computationally expensive (sticking HTML together is sadly rather time-consuming) BUT scales very well - this means that you can simply add more tin when it's not fast enough. On the other hand, back-end servers can do a lot more work, but scale much less well - e.g. databases - you cannot simply add more servers because there are consistency / synchronisation problems to contend with which limit scalability.

MarkR
+1 If you are adamant you need some parts of the page to be dynamic, you must really evaluate if caching fragments of the page is worth the effort. With fragment caching you will increase your capacity somewhat, but you must still invoke the PHP interpreter for every page request, thus limiting you to far below what you can achieve with caching entire pages.
Ben James
+3  A: 

A possibility I've used a couple of times is to :

  • generate the page and store it into the cache, containing something like "Hello, %%PLACEHOLDER_NAME%%" instead of the real name.
  • when a user loads the page :
    • load the cached page
    • do a (quick) str_replace to replace the %%PLACEHOLDER_NAME%% tag by the user's name
    • send the "partially dynamic" page you've creaeted this way.

It means you'll have to do some PHP manipulations, and can't cache the whole page nor serve it as a static file...

... But it also means that almost the whole page will be in cache -- you won't have to do any database query, for instance, if the name is stored in session.

(Some will say it's a bit "dirty" -- but it works really well when there is only one or two small portions that have to be dynamic, which seems to be the case, in your situation)


And if you, one day, start having "too many" of those placeholders, you'll have to consider not caching the page, but the data that are needed to generate the page.

It means you'll have to fetch the data from cache and glue them together to generate the page -- but, this way, you'll still avoid some number of SQL queries, as most of your data will be loaded from cache.

Pascal MARTIN
+1  A: 

You can use User Specific Parameters as the Cache_ID or Cache_ID_Key used in most Cache Libraries out there:

example:

$id = sh1($userMail);
$cache->save($id);

This is a minimal example. The idea is "the key should include user specific information", that is unique to each user.

Hope you get the idea.

andreas
this might help me load specific portions of the page...not a bad idea
johnnietheblack
+1  A: 

Which template engine are you using? Smarty ? if so then you could force to not cache some dynamic parts of a webpage like this

{nocache}
Hello {$username} This is your Email {$email}
{/nocache}
streetparade
actually i rolled my own to kinda learn the guts...not a bad idea though. but sounds fairly complicated with potentially little benefit...right?
johnnietheblack
Smarty isnt complicated. Its very easy to use, and its very good documented. I can recommend to everyone which have the need to separate aplication logic and the design logic
streetparade
+1  A: 

Where do you want to cache?

On your server? You might want to look at Smarty.

On proxies / clients? Then make the html page cacheable, replace any dynamic content with empty divs and write in the values using javascript - the javascript might cache some info in cookies and go back to the server for the rest.

Or have a look at the 'Varies: Cookie' header for how to make session oriented caching.

C.

symcbean
Smarty is cool and i can recommend it to everyone :-)
streetparade
+1  A: 

It's honestly probably overkill for what you want, but ESI addresses the issues you're facing.

However, you might also consider this: just how much of your traffic is logged in? For many web apps, 90%+ of traffic is anonymous, and all anonymous pages render identically. Simply caching anonymous pages may give you much of the benefit you're looking for, without much work at all.

Also, consider caching any small parts of the page that may be reused across many pages -- e.g., if you have a tag cloud that shows on all pages, and takes 200 ms to generate, cache that.

Frank Farmer
+1  A: 

Don't cache the whole page - just cache the part that needs actual caching (e.g. the part that will save you from opening a database connection). Then the rest of the page can still be dynamic and I would assume you're storing the username in a session variable, so you can still do e.g.

echo "Hello ".$_SESSION['username'];
Sean