usingcaching
Http caching can make a big difference to the speed of your site

Speed up your web pages with http caching

Luke Amery12 July 2008, 7:21 PM

A Tag Short | Http caching is really simple, yet it' s surprising to see how little of it is put to good effect. Luke Amery explains how it works.


In an earlier blog, I focused on making the best use of the http stack in the browser and made a brief mention of http caching. The concept is really simple, yet it is surprising to see how little it is used.

So what is it? Http caching is a mechanism that allows the skipping of either whole http requests, or skipping the download of the http response.

Looking back at the http connection entry shows the fewer http requests we are making the lower the latency on receiving the content that makes up our web page (remember, you can’t buy lower latency (past a point)). If we apply the old performance adage – “I can do nothing really, really fast” – we can’t do better than skipping whole requests in the page download / render process. If we can’t skip the request, we can at least skip downloading the content.

So how does it work? There are two concepts at play here. The first is content caching - skipping the download. The second is content expiration - skipping the request altogether. Content caching is mandatory, content expiration doesn’t work without it, and clearly content caching is going to require a cache. Http creates a model that allows caching through a hierarchy of “agents”. The cache furthest from the server (and hence closest to the browser) is the browser cache. If you are coming from windows with Internet Explorer you will likely know this as “Temporary Internet Files”. Under the hood most browsers are doing a little in memory caching of various very recently used objects. The older page elements flow back into browser history the more likely they are only going to appear in the disk cache until they eventually disappear off the local machine entirely in a least recently used fashion.

The next cache up the tree is the proxy server. Not everybody on the Internet makes use of a proxy server. Proxy servers are just like a browser cache; however, they can be shared by a group of people because they operate on the network not on a local computer. I would presume most people connect straight from browser to end server. However, corporate users often end up behind a proxy server. They do end up receiving benefits of company wide caching of http objects, but generally this a secondary concern (logging usage of company Internet connections often being the primary motivator). Additionally, some people who don’t think they are using proxy servers in fact are! Lower quality ISP’s will place a transparent proxy (one that you use without actually asking for) between you and the Internet for web based traffic. This will reduce the ISP’s overall bandwidth requirements or allow heavier over subscription of pipes (especially when the transparent proxy server is configured to override the caching guidelines sent by end servers) and in some cases limit your ability to receive the most up to date content or foul up services that detect things by IP address. Here is a hint - there is a reason TPG is inexpensive. As a side note - there can be more than one proxy server in play.

The next level up, which is not defined by the Http standard, is caching within the end server(s). The end web servers actually producing the final content can use caching internally (a simple way of doing this is to run a proxy server internally within the hosting configuration) this might be done in the case where content being served is time consuming to generate.
Back at the Http level the caching is controlled through request and response headers. Content caching uses the following headers during the web server response:

  • Date – not specifically a header used for caching, however, it does come into play as the down stream Http clients can’t guarantee the clock on the web server is synchronised with theirs, so this header sets up the time base line for the response.
  • Last-Modified – returns a timestamp indicating when the object being requested was last modified. Plain old web servers handing out static content from a conventional file system find this value readily available.
  • Etag – this header represents a particular version of the object being requested. A server can pack any reasonable amount of data into this header (as long as it is in the standard ASCII printable range, which is why most often it is implemented as a base64 encoded blob). This header allows a web server and an Http client to get very specific about a particular version of a resource being sent around.

When an http client (a proxy server or a web browser) wishes to make a request, if it already has a copy of what was at a particular URL (including the last-modified and or etag header values) it can make a “conditional GET” request. Simplifying a little a conditional get comes in the form of “If-Modified-Since” which takes as input the stored last modified value or an “If-Match” request which takes as input the stored etag value. The etag If-Match model was introduced in http 1.1 and represents a much tidier model that can cover more scenarios more easily, however, the last modified If-Modified-Since model generally has wider support as it was in Http since the beginning (this is much less of a problem these days, even up to five years ago it was something to consider as the proliferation of outmoded proxy servers still communicating solely via http 1.0 would cause issues).

So now this is crystal think of all those dynamic web pages (built using your favourite dynamic web page environment, Classic ASP, Cold Fusion, ASP.NET, PHP etc..). Imagine how much server load and bandwidth could be saved if those pages where possible had have been sending an etag and responding with an http response of 304 Not Modified and skipping the page execution and not sending the content.

Fortunately, this caching mechanism is in play automatically on static content on all but the most basic of web servers, so there is nothing tricky that has to be done if using standard web technologies.

Of course there are still limits here, for example, if the page content is continuously varying (like showing the current server time) content caching isn’t going to win big, in fact it would be better to turn caching off in that scenario.

What about the case when a web page has information that is specific to a particular user? The Cache-Control header has a feature that allows where in the cache hierarchy the caching is to be performed – at proxy servers or in user’s browser caches. This is done by setting a public or private sub option as appropriate.

Content expiry is the cherry on the cake. When used in concert with content caching we can have a proxy server or browser skip making web requests altogether – as mentioned previously, that is really going to help keep those two concurrent http connections pumping. The following headers come into play for content expiry:
  • Expires – this header represents a date and time at which point the http client should consider any previous response as needing a re-request. The previous value may have changed or been deleted. The re-request can use the content caching mechanisms if they were available in the original response. The value in the expires header is supposed to be compared to the Date field in the response (just as last-modified could be due to clock synchronisation).
  • Cache-Control – this header is grants lots of functionality to the caching mechanism (more than just expiration). For the expiration feature, we can apply a max-age or s-maxage sub value. Max-age is the number of seconds this content is good to use without re-requesting from the server. S-Maxage is identical but is provided as an override mechanism for proxy servers.

To force a web page to reload from the server every time we can use an expiry time in the past or a no-cache or max-age value of 0 in our cache-control header.

There is an interesting opportunity here. Web servers generally operate on individual files without any knowledge of the interlinking of content that html provides (that interlinking actually happens in the web browser). Content Management Systems, however, potentially could provide a higher level view of things. Because a content management system potentially knows which pages link to which media it would be possible to provide a unique url for each object on a per version basis. If this infrastructure was in place the response headers for media could be setup to perform content expiry well into the future beyond what would normally be used. As changes are made to a web page the urls linking the media would also change and therefore the previously cached content would not be returned when accessing a page. I don’t know of any Content Management Systems that work like this, but if one did it sure would be fast to browse.


All "A Tag Short of Compliance" Blogs


In his real job, Luke Amery works on shopping cart software. He is the technical director of On Technology, Australia's leading e-commerce development company.

Post your comment



anonymous user Anonymous user


Tags