Search code examples
ruby-on-rails-3herokuhttp-headersbrowser-cachecache-control

Keep the assets fresh in browser and cancel the freshness check request of the cache [for rails 3.1 app on heroku]


I have lot of small images (of sizes ~3kb or so) and lot of css and js files. After the first request tey are getting cached on the browser, but when I reload the page the browser is trying to check the freshness of the cached content (by setting the If-Modified-Since etc) and gets the response 304 not modified. Each of this validation request seriously increase the page load time (say 20 time 300ms).

How can I cancel this cache freshness check with the server from the browser? How can instruct the browser to use local cached files/images for certain time (say 1 hour) without re-validating or checking the freshness of the local cache with the remote server for every reload with that time period?

sample small image fetch header details below [using rails 3.1, on heroku]:

Response Headers

    HTTP/1.1 304 Not Modified
    Server: nginx/0.7.67
    Date: Thu, 10 Nov 2011 17:53:33 GMT
    Connection: keep-alive
    Via: 1.1 varnish
    X-Varnish: 1968827848
    Last-Modified: Tue, 08 Nov 2011 07:36:04 GMT
    Cache-Control: public, max-age=31536000
    Etag: "5bda917d22f8a144c293f3f19723dbc6"

Request Headers

    GET /assets/icons/flash_close_button-5bda917d22f8a144c293f3f19723dbc6.png HTTP/1.1
    Host: ???.heroku.com
    User-Agent: Mozilla/5.0 (X11; Linux i686; rv:6.0.1) Gecko/20100101 Firefox/6.0.1
    Accept: image/png,image/*;q=0.8,*/*;q=0.5
    Accept-Language: en-us,en;q=0.5
    Accept-Encoding: gzip, deflate
    Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Connection: keep-alive
    Referer: http://???.heroku.com/
    Cookie: ???
    If-Modified-Since: Tue, 08 Nov 2011 07:36:04 GMT
    If-None-Match: "5bda917d22f8a144c293f3f19723dbc6"
    Cache-Control: max-age=0

Solution

  • This line:

    Cache-Control: public, max-age=31536000
    

    is telling the browser to not ask for updates for a long time, and store the files in a publicly accessible cache (which hear means public to the local machine - not the general public). Your browser should therefore not really be re-checking those files. Have you tried another browser to verify this behaviour exists elsewhere?

    Saying all of this though, considering that your files are coming from the varnish cache and not your dyno, and are being returned as HTTP 304, 300ms for 20 files sounds like a very long time. However, This should be barely perceptible to the user.