Search code examples
ruby-on-railsrubyherokuamazon-cloudfront

Setting Asset Cache Expiration in Rails / Cloudfront / Heroku


I'm getting errors from the Google pagespeed tool saying that cache expiration is not specified for my assets.

I'm serving asserts through cloudfront, and my site (Ruby on Rails) is hosted on Heroku

https://www.driverhunt.com/…9a42dc64767309bbb76af8a1eaef10b3c0cb.css (expiration not specified)
https://www.driverhunt.com/…74901ff9e954e9fca26f71542e8fc8d807684.js (expiration not specified)
https://www.driverhunt.com/…ad7b9e065ed95559bdf1c426bc94834f09e0.jpg (expiration not specified)

Firstly, it looks like things AREN'T being served by cloudfront. Second:

Is this a cloudfront issue, a heroku issue, or a rails issue? Can it be solved programatically, or do I need to fiddle with the heroku/cloudfront settings?


Solution

  • Set the response header

    To enable browser caching you must set the Cache-Control and the Expires response header.

    Debugging tip

    To see your existing cache settings, use your browser's debugger. For Chrome, while on any page in your app, open the debugger and look under:

    enter image description here

    It's important to see what effect your code changes make. Run this on your app as is and get a baseline Response header.


    Setting the response headers

    When you have access to the server config files setting caching on Linux running Apache or Nginx is simple. But it's my experience that Heroku does not permit you to modify server config files directly.

    Without the capability to modify .htaccess or nginx.conf on the server you have 2 options:

    1- Implement caching for your rails app at the controller level, e.g.:

    def show
      @company = Company.find(params[:id])
      expires_in 3.minutes, :public => true
      # ...
    end
    

    Which is an admittedly hideous solution.

    2- The other option Heroku offers is HTTP caching using Rack::Cache (Memcachier Heroku add-on). I have no experience with this, so no comment.

    Conclusion

    Heroku provides a wonderful and simple deploy environment, but to offer that simplicity, they have locked down configuration. I used Heroku to develop and deploy an app in test mode, but moved to a VPS where I could implement server side optimizations, such as caching to launch the app.

    P.S. To address the CDN part of the question: Since it is your sever setting the response headers, I don't think the CDN config impacts caching.