Friday, November 06, 2015

Don't throw away cached data just because it might have expired

Following on from my post about etags, earlier this week, there's something related to caching that I've seen many apps do wrong.

It basically comes down to this: just because the timespan that a server says content can be cached for has expired doesn't mean that the content will be changed.

Let me demonstrate by way of an example.

Imagine this scenario:

- App want to display an image from the web.
- App requests the resource
- Server returns resource and also an expiry header saying it's good for 24 hours
- App displays the image and recognises the header so saves a copy of the image for later reuse. (That it recognises the header and caches a copy of the image is already better than many but let's keep going.)
- App is closed after two minutes of use
- App is reopened six hours later
- App shows image from cache as it hasn't expired.
- App is next opened two days later
- App ignores the cached image, as it's expired, and so goes to the server to get it again.

Notice that last point.
What if the image hasn't changed?

Was the best thing the app could have done to:
- briefly show a space/placeholder while the image is downloaded again?
- waste data downloading the same thing again?

Wouldn't it be better to:
- keep showing the original image
- check if the image is still valid. (using, for example, etags or if-modified-since headers)
- if it is still valid, then update the expiry time/TTL stored locally
- if it is no longer valid then update the locally cached and displayed image.

Yes, it's a little bit more work but it's a better experience.
- less, duplicate, content need be downloaded
- consistently display images that haven't changed

It may not by the right approach for every image and is dependent upon server support but definitely worth considering.

1 comment:

I get a lot of comment spam :( - moderation may take a while.