Huddle Blog
Salt beef on rye
Friday, May 16, 2008
To wrap up this week of great sandwiches here at Huddle, our CTO Jonathan has suggested we mention the classic salt beef on rye. Whilst I personally like my salt beef (or corned beef if you come from the US) smothered in butter in a fresh poppy-seeded bagel, Jonathan loves going to the Selfridges food hall and ordering the following:
Two slices of rye bread, heaps and heaps of hot salt beef (preferrably freshly carved rather than microwaved!) a layer of American mustard and gherkins on the side.
To be honest, this is a difficult sandwich to beat – nothing satisfies quite like it and although it’s somewhat of an acquired taste it’s incredibly addictive!

Tuna & soy sauce special
Thursday, May 15, 2008
Today we review a personal favourite of Charlie, our Commercial Director – who has a new take on the classic tuna mayo sandwich. Sounds to me like he’s created a classic…
Take a mixing bowl and spoon in a tin of tuna – then add a dash of soy sauce, a squeeze of salad cream, mayonnaise and some ground black pepper. Then finely chop some red pepper and red onion and add a dash of hot pepper sauce and mix everything together.
Spread some salted butter on two thick slices of granary bread and wack in the tuna mix – Charlie swears this is the best tuna sandwich you’ll ever taste!

Chargrilled chicken & mango chutney
Wednesday, May 14, 2008
Another member of our development team Jenna has this sandwich suggestion for this next installment of our British Sandwich Week spectacular. She says:
This has to be one of the yummiest sandwiches I’ve ever tried… Easy to make, pleasing on the tongue and always fills an empty stomach!
What you’ll need:
Fresh uncut loaf of brown/white bread, butter, mayonnaise, sliced chargrilled chicken (you can buy it pre-cooked and sliced from tesco! EASY), cucumber, lettuce and the most important ingredient of all…. mango chutney.
How to make it:
Take your fresh loaf and cut two generously sized slices of bread. Butter one side of each and spread your chicken evenly onto one of the pieces. On that same piece add your cucumber, lettuce and any other salad ingredients you fancy. Add mayonnaise and mango chutney (the more the merrier) to the other slice, place it on top and carefully cut in half.
YUM! :)
Cache & version your CSS/JavaScript
Wednesday, May 14, 2008
Recently we’ve been working on improving the caching within the website to improve performance for the user. After reading around, we found the following rules to be valuable.
- Cache your CSS/JavaScript forever (set a long, long expiry)
- Handle updates by changing the URL of your CSS/JavaScript
When caching “forever” the main problem is if you release an update to “styles.css” the browser caches the URL of that file, but won’t pick up any future updates unless the user clears their browser cache (we’re often telling people to “Ctrl + F5”). By changing the URL of the file, the browser thinks it’s requesting a new file, and your updates get applied. But how do you go about doing this without it becoming a pain to manage?
One common solution we found was to add a querystring to the url for the CSS/JavaScript. For example:
\webresources\css\styles.css?version=3
This is commonly used, but not 100% effective. According to the HTTP caching specification, the user agent should cache a URL ignoring the querystring. Carl Henderson goes into more detail about it in his article, Serving JavaScript Fast. So, according to the specification, “styles.css?version=3” is no different from “styles.css” as “?version=3” is ignored.
Firefox and IE ignore this specification, so using a querystring will still work. However, browsers such as Opera and Safari do do apply the HTTP caching specification, so using a querystring won’t work.
Anyway to be safe, we took a different approach. Using the C# codebehind of our MasterPage we read the LastWriteTime of the styles.css file and include this in the filename. For example:
<link id="CssMerged" href="/webresources/css/styles.{0}.css" media="screen, projection" rel="stylesheet" type="text/css" runat="server" />
/webresources/css/styles.{mmhhddMMyy}.css
/webresources/css/styles.1220010108.css
Here’s a snippet of the C# code used:
protected override void OnPreRender(EventArgs e)
{
CssMerged.Href = string.Format(CssMerged.Href, GetVersion("/webresources/css/merged.css", "CssVersion"));
}
protected string GetVersion(string filePath, string cacheName)
{
FileInfo file = new FileInfo(Server.MapPath(filePath));
string date;
if (HttpRuntime.Cache[cacheName] == null)
{
if (file != null)
{
date = file.LastWriteTimeUtc.ToString("mmhhddMMyy");
HttpRuntime.Cache.Add(cacheName, date, null, DateTime.Now.AddMonths(3), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.Normal, null);
}
else
{
date = "0000000000";
}
}
else
{
date = HttpRuntime.Cache[cacheName].ToString();
}
return date;
}
Using Ionic’s ISAPI Rewrite Filter we have a simple rule to ignore the “.1220010108” part of the URL request. So that styles.1220010108.css points to styles.css.
RewriteRule ^/webresources/css/(.*).([0-9]{10}).css /webresources/css/$1.css [I]
RewriteRule ^/webresources/javascript/(.*).([0-9]{10}).js /webresources/javascript/$1.js [I]
We could write a more generic rule, but for now the above is fine. This was easy to apply as we only have one file for our CSS and one for our JavaScript. For developing we keep all of our CSS and JavaScript in separate files. However, when performing a release build we merge all of the CSS/JavaScript into one file each to reduce the number of requests needed in a single page load. We then compress and validate it using YUICompressor. More on that in another post though.
Moving forward, we may move to IIS7 eventually. In doing so it would mean we could implement something such as Url Rewriter (rather than Ionic’s ISAPI Rewrite Filter) within the web application to handle the rewriting.
Also generating the name using the LastWriteTime isn’t ideal. We may look into injecting the version number into the Web.Config when the build is done using CruiseControl.Net.
The main disadvantage to using an ISAPI filer (with IIS6) is that if it falls over, your site isn’t going to have any CSS or JavaScript. We’ve actually had this happen so are stepping carefully with the current solution. If it does pose a problem, again using CruiseControl.Net we could potentially rename styles.css to styles.xxxxxxxxxx.css, and include xxxxxxxxxx in our Web.Config. More on that in the future though.