Dynamically Generated CSS Output Caching

In my application, the user has the ability to change the CSS of his site.

This is unlikely to change so often, but when you need it, we need to make sure that they and their website visitors instantly see the results.

We record the date and time when the user updated their CSS, so a simple solution would be to simply add a timestamp to the URL.

However, I would like to know if I can automatically adjust the cache headers to force the browser to re-request the CSS file if it changes.

+4
source share
2 answers

If you include the hash in your URL, i.e.

http://server.example.com/styles/css.css?hash 

it will reload when the hash changes because the browser will select it from the new URL:

Version 1:

 <style type="text/css" link="styles/css.css?hash=v1" /> 

Version 2:

 <style type="text/css" link="styles/css.css?hash=v2" /> 

Client caching is a client issue, let them do as they see fit: a new URL means that the resource has been changed, so it needs to be reloaded. Keeping the same URL with cache management headers can lead you to a world of pain due to different client implementations.

If you put cache control headers (last-modified, expires, ETAG), you cannot be sure that the CSS will be updated after changing it:

  • because aggressive browser caching (or proxies) can ignore them.
  • since you can service V1 on May 1, with an expiration date on June 1, upgrade it to V2 on May 15, and your customers will have to wait 15 days to get the new version.

In the case of a URL hash, the worst case scenario is that the client does not cache your css, but the user interface does not change, as it always gets the latest version.

With the expiration date or the last modified date, the worst case is that the client receives the old version and this will change the user's work :)

+4
source

Thanks to Mathieu's answer, I use a combination of output caching and version numbers to handle cache invalidation.

Output Cache Profile:

I created the following extension method to add a timestamp:

  public static string AppendTimeStamp(this string src, DateTime lastModified) { if (string.IsNullOrEmpty(src)) return src; return string.Format("{0}?v={1}", src, lastModified.ToString("yyyyMMddHHmmss")); } 

Using:

 <link rel="stylesheet" href="@Url.Content("~/assets/usercss").AppendTimeStamp(CustomizationSettings.LastModified)"/> 

In cases where you do not want to cache the file, you can simply pass DateTime.UtcNow as the last modified date.

+1
source

All Articles