Bulletproof Rails Asset Caching(eng.wealthfront.com)
eng.wealthfront.com
Bulletproof Rails Asset Caching
http://eng.wealthfront.com/2011/02/bulletproof-rails-asset-caching.html
5 comments
It's difficult for this to not sound snarky, but my definition of bulletproof doesn't involve parsing CSS with bash and awk.
<snark>You'd prefer C?</snark>
Seriously, though, how would you improve the solution? What would decrease the likelihood of serving the wrong asset or no asset at all? I'm sure there are other interesting solutions to this problem, but are they as complete and in some measurable way better?
Disclaimer: I work with Jared and enjoy the benefit of the solution as described.
Seriously, though, how would you improve the solution? What would decrease the likelihood of serving the wrong asset or no asset at all? I'm sure there are other interesting solutions to this problem, but are they as complete and in some measurable way better?
Disclaimer: I work with Jared and enjoy the benefit of the solution as described.
You've missed the point. 90% of Rails websites behave badly every time they're deployed, and the developers don't even realize it. I included our build scripts in the post to illustrate how simple it is to fix the problem. The important thing is that people reliably version their asset URIs, not what tools they use to do it.
Looks interesting. Pre-generating asset files for deployment might also be a nice alternative to the usual tricks[1] for using SASS (or other CSS generators) with Heroku, which have rack middleware reading a cache.
(Unfortunately, the code samples were a hard for me to read, in both Firefox and Chrome --- all the newlines seem to have somehow gotten squeezed out...)
[1] https://github.com/pedro/hassle
(Unfortunately, the code samples were a hard for me to read, in both Firefox and Chrome --- all the newlines seem to have somehow gotten squeezed out...)
[1] https://github.com/pedro/hassle
Might I suggest Jammit? You can write a rake task that packages all the assets, uploads the files to s3 and deletes the asset folder. Change the asset host to your s3 bucket or Cloudfront. Whenever you deploy, do 'rake deploy:assets' and you're set.
http://documentcloud.github.com/jammit/
http://documentcloud.github.com/jammit/
I believe that in Rails 3.1 they're including a fix for this, so work arounds like this won't be necessary anymore :)
Got a link to details? I'd be surprised, since any correct solution requires two-stage deployment and keeping old assets around. These capabilities are beyond the scope of a web server framework. The Rails team could certainly educate Rails developers and choose conventions that make correctness easier.
[deleted]
Sprockets 2 (not yet a gem, point to git) makes a lot of this easier. You can put extra extensions on your files to get them processed with ERB or similar before they're served, so you can actually append auto generated asset versions to URLs in CSS files if you want. It also sends appropriate status codes when there's a stale version (410 Gone).
Sprockets 2 behind Amazon CloudFront does asset handling almost exactly like I want it done.
Sprockets 2 behind Amazon CloudFront does asset handling almost exactly like I want it done.
But any dynamic processing of stylesheets sacrifices performance. It means they have to be served by Rails. Preprocessing before deployment frees you to host them anywhere, ideally closer to your users.
I get exactly that with CloudFront, a custom origin (with Sprockets), and appropriate HTTP headers. If CloudFront doesn't see a file, it asks Sprockets for it and caches it however long I tell it to.
You can do the same with Varnish if you don't want to use Amazon's CDN. Having run a large site with prebuilt assets for several years, I really enjoy not having to do it anymore.
You can do the same with Varnish if you don't want to use Amazon's CDN. Having run a large site with prebuilt assets for several years, I really enjoy not having to do it anymore.
Great post with lots of good info. Especially important for apps that utilize a lot of JavaScript. We've been getting bit by this lately in ASP.NET MVC since it has no built in strategy for dealing with browser asset caching/ expiration.
Compass has helpers that use the Rails asset link helpers to link to images. There are sprite helpers available as well.
AssetFingerPrint is a Rails plugin that tosses and MD5 into the asset link automatically.
Jammit compresses CSS/JS files, and the fingerprint of the resulting compiled files are picked up by AssetFingerPrint.
Thats how we roll at Poll Everywhere.