BrowserCaching » History » Version 3

« Previous - Version 3/13 (diff) - Next » - Current version
dj jones, 2014-09-01 15:34
added new broser caching section - due to complexities of doing it right, due to quirky Redmine mis-use of .js for user-content files


General Background: as to why caching in browser is a good thing

It is good practise on any website to let the browser cache objects that are static - ie don't contain user content, and are the same for hours, days or weeks.

(This in general means files like: .css, .js and image files)

But some content does change very fast, so must not be cached by the browser.

If the browser is told 'don't cache this object':
it knows not to. This is what Websites (and Redmine) do on the pages that may change: eg an issue page: it will put into the HTTP header that message.

But in the absence of that - if the browser is not sure about a page component
, that it already has recently downloaded, it will send a 304 request to the server: saying 'can you tell me, is this file still not stale'. And with a 304 the server does not need to send the whole object again: just a short 'yes, that is still fresh' answer.

In Redmine's default set-up: it generates a lot of 304 connects on every page: you can see these in a tool like Firebug. One for every css and .js file etc. Many

These are bad for the user experience: because the browser has to wait for these responses before it can carry on and build the page.

So we need to tell the browser that these objects will not be stale for a long time

There are easy ways to configure Apache and nginx to do this: by telling them to set the 'Expiry' date in the HTTP Header well into the future: so that the browser knows: OK, this objects is not stale, because we are still before the expiry date'.

Thus when a new user visits Redmine, their browser on the fisrt page will GET the .css and .js files etc, but on pages after that: does not need to get them again.

The users experience faster web page builds!

The Problem with Redmine
Unfortunately, RedMine also uses .js file names, for things that DO content user content: ie things that should NOT be cached in the browser.

So this means; if in Apache/nginx you add a simple config, to cache anyting that is named *.js: then your Redmine will break!

See the Issue #17770 - where this problem is reported, to see if the RedMine team can change RRedmine, to STOP using the .js in bad places.

Tne places it breaks if you use a simple config are: (a) when editing a journal in an issue (b) when uploading a file to an issue

h2.The work round for RedMine

Is to use a more complex configuration: that also checks which directory the .js file is in before setting the cache heading.

Etienne suggested this nginx configuration (see Issues #13564):

location ~* ^(?:(?:plugin_assets/|themes/).+/)(?:javascripts|stylesheets|images)/.+\.(?:css|js|jpe?g|gif|htc|ico|png|html)$ {

The simple case, that will break Redmine, does not care about which directory eg:

location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
expires 365d;